Troca de colunas ou linhas em uma matriz Ruby
-
27-10-2019 - |
Pergunta
Quero trocar linhas ou colunas em uma matriz de matrizes (ou seja, uma matriz).Eu encontrei esse método de troca online e o estendi com minha função mutate
, onde board.matrix
é a matriz de matrizes:
# 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
Agora ele faz o que deveria para as linhas:
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
Mas não para colunas.Por que isso?
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
Solução
Como no código a seguir você não transformou o Array matrix
está apontando, você apenas atribuiu um novo Array a matrix
, que é uma variável local:
temp = matrix.transpose
temp.swap!(rand_a, rand_b)
matrix = temp.transpose
Você pode substituir esse código por este:
matrix.each do |row|
row[rand_a], row[rand_b] = row[rand_b], row[rand_a]
end
Outras dicas
O problema é que você apenas define a variável local matrix
para o novo objeto criado por #transpose
.
Em seguida, você imprimiu o objeto de matriz original que aparentemente é board.matrix
.
Embora você também tenha usado a variável local para trocar as linhas, nesse caso o local era uma referência ao objeto original, então elas eram iguais e "funcionou" do ponto de vista da sua rotina de saída.Mas com as colunas, um novo objeto foi retornado por transpose
e board
nunca foi atualizado.