There is a problem that I solved in theory, but the value in the temp array does not change. What is the catch?

=begin Заполнить квадратную матрицу размера n на n натуральными числами от 1 до n**2 в указанном порядке: | 1 2 3 | | 6 5 4 | | 7 8 9 | =end glob_arr = [] temp = [] puts "Введите n" n = gets.chomp.to_i for i in 1..n temp<<i end for i in 0..n-1 if i%2==0 glob_arr << temp else glob_arr << temp.reverse end temp.reverse.each{ |e| e+=1 } end glob_arr.each { |e| puts e.to_s } 

    3 answers 3

    You can do the following:

     glob_arr = [] puts "Введите n" n = gets.chomp.to_i temp = Array.new(n, 0).fill { |i| i + 1 } n.times do |i| if i.even? glob_arr << temp.dup else glob_arr << temp.reverse end glob_arr[i].map!{ |e| e += n * i } end glob_arr.each { |e| puts e.to_s } 

    The result is the following output

     Введите n 3 [1, 2, 3] [6, 5, 4] [7, 8, 9] 

    The catch is that you assign the same temp array to the elements of the glob_arr array. In ruby, everything is an object, and objects are passed by reference. As a result, changing then one row of the matrix, you will affect all three rows. Therefore, it is better to clone temp , for example, using the dup method — then the rows of the matrix will be different arrays that can be converted independently of each other.

    • Once again you bailed out. I had thoughts on this. But about dup did not hear. It is necessary to tighten the theory. I felt uncomfortable. - QWD666 8:50 pm
    • @ QWD666 Feel free to ask what we know, tell you what we can - help :) - cheops
    • @cheops I understand correctly that instead of this glob_arr << temp.dup.reverse you can write glob_arr << temp.reverse , and nothing will change? - jisecayeyo
    • @jisecayeyo yes, absolutely, right, in this line of dup, redundant, since reverse itself creates a copy of the array. Thanks for the comment, corrected the answer. - cheops

    Well and magic

     n=9 result=(1..n).to_a.each_slice(Math.sqrt(n)).each_with_index.map { |x, i| (i.even?) ? x : x.reverse } p result 

    will issue

     [[1, 2, 3], [6, 5, 4], [7, 8, 9]] 

    True, the problem reads "1 to n ** 2", but the author takes n as a finite number, and does not square it, so we take the root to calculate the size of the array.

    • Do you want more intense magic? I have it! (1..9).each_slice(3).map.with_index { |x, i| i.even? ? x : x.reverse } (1..9).each_slice(3).map.with_index { |x, i| i.even? ? x : x.reverse } - D-side
    • @ D-side on the same tryruby.org "# <NoMethodError: undefined method` each_slice 'for 1..9: Range> ". The map.with_index didn’t work for me from the very beginning and didn’t become a wise man. - vitidev
    • There is old, I suppose. I drove to 2.2. - D-side

    To change the values ​​of an array, use the map function. The function will return a new array with changes, without affecting the data in the original array. To replace the data in the original array, you need to use the map! function map! .
    In your case, temp.reverse!.map!{ |e| e+=1 } temp.reverse!.map!{ |e| e+=1 } , or temp.map!{ |e| e+=1 } temp.map!{ |e| e+=1 } reverse !.
    The exclamation point at the end of the methods in Ruby means that the change will affect the source data.
    If we execute temp.reverse.map!{ |e| e+=1 } temp.reverse.map!{ |e| e+=1 } , then the reverse method will return a new array with modified data and the map! method map! will be called for a new array, so you will not notice the changes.
    The above will only help to change the value of the array, but for the correct solution of the problem, see the answer @cheops.

    • I tried it through the map, but this is the problem, it either changes all the data to the same, or it works the same way as in my example. - QWD666
    • @ QWD666, you used map! (with an exclamation mark)? - jisecayeyo 8:32 pm
    • Yes. And also without him. - QWD666
    • @ QWD666, problem in the reverse method. First temp.map!{ |e| e+=1 } temp.map!{ |e| e+=1 } , and then temp.reverse! . Or temp.map!{ |e| e+=1 }.reverse! temp.map!{ |e| e+=1 }.reverse! - jisecayeyo