Reputation: 2639
I'm using this Matrix class: http://ruby-doc.org/stdlib-2.0.0/libdoc/matrix/rdoc/Matrix.html
I'm instantiating it this way:
@matrix = Matrix.build(3,3) { |row, col| Cell.new }
How can I get the elements from both diagonals? I found I can get the elements from the upper left to the lower right diagonal this way:
@matrix.each(:diagonal).to_a
But I cant find a way to get the elements in the upper right to lower left diagonal.
Upvotes: 1
Views: 825
Reputation: 110745
Suppose:
require 'matrix'
m = Matrix[[1,2,3],
[4,5,6],
[7,8,9]]
#=> Matrix[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
Obtaining the main diagonal is easy. Let's make it a Matrix
method.
class Matrix
def extract_diagonal
each(:diagonal).to_a
end
end
m.extract_diagonal
# => [1, 5, 9]
One way of obtaining the antidiagonal1 is to rotate the matrix "90 degrees" and then take the main diagonal of that matrix. To perform the rotation, here's another Matrix
method I've found useful in various situations:
class Matrix
def rotate
Matrix[*to_a.map(&:reverse).transpose]
end
end
For example:
m.rotate
#=> Matrix[[3, 6, 9],
# [2, 5, 8],
# [1, 4, 7]]
The antidiagonal of m
is therefore:
m.rotate.extract_diagonal
#=> [3, 5, 7]
1. According to Wiki, the diagonal that goes from the top left to the bottom right of a square matrix is the "main diagonal (sometimes principal diagonal, primary diagonal, leading diagonal, or major diagonal)", whereas the diagonal that goes from the top right to bottom left is the "antidiagonal (sometimes counterdiagonal, secondary diagonal, trailing diagonal or minor diagonal)".
Upvotes: 3
Reputation: 121010
Diagonal:
@matrix.square? && ([email protected]_size).map { |i| @matrix[i, i] }
Upper-right⇒lower-left diagonal:
@matrix.square? && ([email protected]_size).map do |i|
@matrix[i, @matrix.row_size - 1 - i]
end
Check for @matrix.square?
ensures that the diagonal exists, after all.
Upvotes: 3