Swapping either Columns or Rows in a Ruby Matrix
-
27-10-2019 - |
Question
I want to swap either rows or columns in an array of arrays (i.e. a matrix). I have found this swap method online, and I extended it with my mutate
function, where the board.matrix
is the array of arrays:
# Swap to elements of an Array
def swap!(a,b)
self[a], self[b] = self[b], self[a]
self
end
def mutate(board)
matrix = board.matrix
random = rand
rand_a = rand(matrix.length-1)
rand_b = rand(matrix.length-1)
puts "Old one:"
board.print_matrix
# We have a 50:50 chance of swapping either columns or rows
if random <= 0.5
# Swap columns: Transpose first
puts "Swapping columns #{rand_a} and #{rand_b}..."
temp = matrix.transpose
temp.swap!(rand_a, rand_b)
matrix = temp.transpose
else
# Just swap rows
puts "Swapping rows #{rand_a} and #{rand_b}..."
matrix.swap!(rand_a, rand_b)
end
puts "New one:"
board.print_matrix
end
Now it does what it should for rows:
Old one:
X X 0 0
0 0 0 0
X X 0 0
0 0 0 0
Swapping rows 1 and 0...
New one:
0 0 0 0
X X 0 0
X X 0 0
0 0 0 0
But it doesn't for columns. Why is that?
Old one:
0 X X 0
0 0 X 0
X 0 0 0
0 0 0 0
Swapping columns 1 and 0...
New one:
0 X X 0
0 0 X 0
X 0 0 0
0 0 0 0
Solution
Because in the following code you did not transformed the Array matrix
is pointing to, you just have assigned a new Array to matrix
, which is a local variable:
temp = matrix.transpose
temp.swap!(rand_a, rand_b)
matrix = temp.transpose
You can actually replace this code with this:
matrix.each do |row|
row[rand_a], row[rand_b] = row[rand_b], row[rand_a]
end
OTHER TIPS
The problem is that you only set the local variable matrix
to the new object created by #transpose
.
Then you printed the original matrix object which is apparently board.matrix
.
Although you also used the local variable to swap the rows, in that case the local was a reference to the original object, so they were the same, and it "worked" from the point of view of your output routine. But with the columns a new object was returned by transpose
and board
was never updated.