Scambio di colonne o righe in una matrice Ruby
-
27-10-2019 - |
Domanda
Voglio scambiare righe o colonne in un array di array (cioè una matrice).Ho trovato questo metodo di scambio online e l'ho esteso con la mia funzione mutate
, dove board.matrix
è l'array di array:
# 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
Ora fa quello che dovrebbe per le righe:
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
Ma non per le colonne.Perché è così?
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
Soluzione
Poiché nel codice seguente non hai trasformato l'Array matrix
a cui punta, hai semplicemente assegnato un nuovo Array a matrix
, che è una variabile locale:
temp = matrix.transpose
temp.swap!(rand_a, rand_b)
matrix = temp.transpose
Puoi effettivamente sostituire questo codice con questo:
matrix.each do |row|
row[rand_a], row[rand_b] = row[rand_b], row[rand_a]
end
Altri suggerimenti
Il problema è che imposti solo la variabile locale matrix
sul nuovo oggetto creato da #transpose
.
Quindi hai stampato l'oggetto matrice originale che apparentemente è board.matrix
.
Sebbene tu abbia utilizzato anche la variabile locale per scambiare le righe, in quel caso local era un riferimento all'oggetto originale, quindi erano gli stessi e "funzionava" dal punto di vista della routine di output.Ma con le colonne un nuovo oggetto è stato restituito da transpose
e board
non è mai stato aggiornato.