Échange de colonnes ou de lignes dans une matrice de rubis
-
27-10-2019 - |
Question
Je veux échanger des lignes ou des colonnes dans un tableau de tableaux (c'est-à-dire une matrice). J'ai trouvé cette méthode d'échange en ligne, et je l'ai étendu avec mon mutate
fonction, où le board.matrix
est le tableau des tableaux:
# 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
Maintenant, il fait ce qu'il devrait pour les lignes:
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
Mais ce n'est pas le cas pour les colonnes. Pourquoi donc?
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
La solution
Parce que dans le code suivant, vous n'avez pas transformé le tableau matrix
Pointe, vous venez d'attribuer un nouveau tableau à matrix
, qui est une variable locale:
temp = matrix.transpose
temp.swap!(rand_a, rand_b)
matrix = temp.transpose
Vous pouvez réellement remplacer ce code par ceci:
matrix.each do |row|
row[rand_a], row[rand_b] = row[rand_b], row[rand_a]
end
Autres conseils
Le problème est que vous ne définissez que la variable locale matrix
au nouvel objet créé par #transpose
.
Ensuite, vous avez imprimé l'objet matriciel d'origine qui est apparemment board.matrix
.
Bien que vous ayez également utilisé la variable locale pour échanger les lignes, dans ce cas, le local était une référence à l'objet d'origine, donc ils étaient les mêmes, et il a "fonctionné" du point de vue de votre routine de sortie. Mais avec les colonnes, un nouvel objet a été renvoyé par transpose
et board
n'a jamais été mis à jour.