Here is my attempt:
array = [1,2,3,4,5,6,7,8,9]
sliced = array.each_slice(3).to_a
# As sliced size is 3, I took 2, i.e. 3 - 1
(0..2).map { |i| sliced[i][i] } #=> [1, 5, 9]
(0..2).map { |i| sliced[i][-i-1] } # => [3, 5, 7]
(0..2).map { |i| sliced[i][i] }.reduce :+
# => 15
(0..2).map { |i| sliced[i][-i-1] }.reduce :+
# => 15
In accordance with the observation above, it seems that in one iteration you can solve:
left_diagonal, right_diagoal = (0..2).each_with_object([[], []]) do |i, a|
a[0] << sliced[i][i]
a[1] << sliced[i][-i-1]
end
left_diagonal.reduce(:+) # => 15
right_diagonal.reduce(:+) # => 15
OOP code style added:
class SquareMatrix
attr_reader :array, :order
def initialize array, n
@array = array.each_slice(n).to_a
@order = n
end
def collect_both_diagonal_elements
(0...order).collect_concat { |i| [ array[i][i], array[i][-i-1] ] }
end
def collect_left_diagonal_elements
(0...order).collect { |i| array[i][i] }
end
def collect_right_diagonal_elements
(0...order).collect { |i| array[i][-i-1] }
end
def sum_of_diagonal_elements type
case type
when :all then collect_both_diagonal_elements.reduce(0, :+)
when :right then collect_right_diagonal_elements.reduce(0, :+)
when :left then collect_left_diagonal_elements.reduce(0, :+)
end
end
end
array = [1,2,3,4,5,6,7,8,9]
sqm = SquareMatrix.new array, 3
sqm.collect_both_diagonal_elements
sqm.sum_of_diagonal_elements :all
sqm.collect_left_diagonal_elements
sqm.sum_of_diagonal_elements :left
sqm.collect_right_diagonal_elements
sqm.sum_of_diagonal_elements :right