Диагональ главной косой (или основная вторичная диагональ ) матрицы nxn
a
состоит из элементов a[n-1][0]
, a[n-2][1]
, ... , a[1][n-2]
, a[0][n-1]]
.
Часть проблемы заключается в том, что переменным не были даны описательные имена. Я написал бы это следующим образом.
def diagonal_difference(arr)
main_diagonal_sum=0
main_skew_diagonal_sum=0
arr.each_with_index do |row, i|
main_diagonal_sum += row[i]
main_skew_diagonal_sum += row[-i-1]
end
(main_diagonal_sum - main_skew_diagonal_sum).abs
end
Я ожидаю, что row[-i-1]
может быть самой запутанной частью кода. Предположим, что i = 0
, затем row[-0-1] #=> row[-1]
, что является последним элементом row
. Когда i = 1
, row[-1-1] #=> row[-2]
, который является ближайшим к последнему элементу row
, и так далее. Вместо этого можно было бы написать row[row.size-i-1]
.
Примечание return
не требуется, если, как здесь, возвращаемое значение последнего выполненного оператора (до возврата метода) должно быть возвращено методом.
Давайте добавим несколько puts
операторов в метод и проработаем пример.
def diagonal_difference(arr)
puts "arr=#{arr}"
main_diagonal_sum=0
main_skew_diagonal_sum=0
arr.each_with_index do |row, i|
puts "row=#{row}, i=#{i}"
main_diagonal_sum += row[i]
puts " row[#{i}]=#{row[i]}, main_diagonal_sum=#{main_diagonal_sum}"
main_skew_diagonal_sum += row[-i-1]
puts " row[-#{i}-1]=#{row[-i-1]}, main_skew_diagonal_sum=#{main_skew_diagonal_sum}"
end
(main_diagonal_sum - main_skew_diagonal_sum).abs
end
arr = [[1,2,3],
[4,5,6],
[9,8,7]]
Основная диагональная сумма равна 1+5+7 #=> 13
, а основная косая диагональная сумма равна 3+5+9 #=> 17
, поэтому мы ожидаем, что метод вернет (13-17).abs #=> 4
.
diagonal_difference(arr)
#=> 4
печатает следующее.
arr=[[1, 2, 3], [4, 5, 6], [9, 8, 7]]
row=[1, 2, 3], i=0
row[0]=1, main_diagonal_sum=1
row[-0-1]=3, main_skew_diagonal_sum=3
row=[4, 5, 6], i=1
row[1]=5, main_diagonal_sum=6
row[-1-1]=5, main_skew_diagonal_sum=8
row=[9, 8, 7], i=2
row[2]=7, main_diagonal_sum=13
row[-2-1]=9, main_skew_diagonal_sum=17
Использование метода Matrix # trace (расширенный)
Сумма элементов на двух диагоналях может быть альтернативно вычислена с использованием метода Matrix#trace
и вспомогательного метода roll
(как при повороте массива против часовой стрелки на 90 градусов), который преобразует диагональ основного перекоса в основную. диагонали.
def roll(arr)
arr.map(&:reverse).transpose
end
roll(arr)
#=> [[3, 6, 7],
# [2, 5, 8],
# [1, 4, 9]]
Это позволяет нам написать следующее.
require 'matrix'
(Matrix[*arr].trace - Matrix[*roll(arr)].trace).abs
#=> 4