this code here:
def create_sym_matrix
ran_arr = Array.new(5){rand(1..100)}
ran_arr[1] = 0
mat_arr = Array.new(5){|i|ran_arr.push(ran_arr.shift)}
Matrix.columns(mat_arr)
end
aa = create_sym_matrix
=> Matrix[[86, 86, 86, 86, 86], [0, 0, 0, 0, 0], [20, 20, 20, 20, 20],
[39, 39, 39, 39, 39], [48, 48, 48, 48, 48]]
Can someone explain to me why it did not rotate? I was trying to get a symmetric Matrix with zeros in the diagonal.
The documentation of Array::new
explains:
new(size=0, default=nil)
new(array)
new(size) {|index| block }
...In the last form, an array of the given size is created. Each element in this array is created by passing the element's index to the given block and storing the return value.
The block {|i|ran_arr.push(ran_arr.shift)}
always returns the same value: the array stored in ran_arr
. The new array contains 5 references to ran_arr
. The rows of mat_arr
contain the same values because there aren't five different rows; it's the same object linked five times.
To fix this you should return from the block a copy of ran_arr
:
mat_arr = Array.new(5){|i|ran_arr.push(ran_arr.shift).clone}
You will notice that it still doesn't generate a matrix with zeroes on the diagonal. To achieve this goal you need to correct the algorithm:
def create_sym_matrix
ran_arr = Array.new(5){rand(1..100)}
ran_arr[4] = 0
mat_arr = Array.new(5){|i|ran_arr.unshift(ran_arr.pop).clone}
Matrix.columns(mat_arr)
end
The output:
Matrix[[0, 38, 8, 48, 73], [73, 0, 38, 8, 48], [48, 73, 0, 38, 8], [8, 48, 73, 0, 38], [38, 8, 48, 73, 0]]