'Add diagonal difference of matrix

HackerRank Diagonal Difference Problem.

Print the absolute difference between the sums of the matrix's two diagonals as a single integer.

Link to problem: https://www.hackerrank.com/challenges/diagonal-difference/problem

I have been trying for hours to solve this problem in Ruby. I happened upon an answer that someone else figured out.

I am now please asking for help in understanding how this method works. I want to understand what it is doing. I am confused by the entirety of the loop.

a.each_with_index do |array, index|
  left_right += array[index]
  right_left += array[-index-1]

Could someone please explain step-by-step what is happening in this block of code so I can learn and better understand Ruby? Thank you.

def diagonalDifference(a)
  left_right=0
  right_left=0
  a.each_with_index do |array, index|
    left_right += array[index]
    right_left += array[-index-1]
  end
  v = right_left - left_right
  return v.abs
end


Solution 1:[1]

See following

11 2 4
4 5 6
10 8 -12
So, a = [ [11, 2, 4], [4, 5, 6], [10, 8, -12] ]

Now ref each_with_index method for a.each_with_index do |array, index|. during first iteration array will be [11, 2, 4] & index will be 0. array[0] = 11 & array[-0-1] i.e. array[-1] = 4 Similarly for second iteration array[1] = 5 & array[-1-1] i.e. array[-2] = 5& so on.

You'll get

2.3.1 :360 > left_right # 11 + 5 - 12
 => 4 
2.3.1 :361 > right_left # 4 + 5 + 10
 => 19 
2.3.1 :362 > v = right_left - left_right
 => 15 

v.abs is used to return absolute difference in case v is negative, Ref abs method of Numeric class.

Note:- return keyword is optional if it is the last non comment line in a method.

Solution 2:[2]

You can use the Matrix library as proposed in this answer.

require 'matrix'
(Matrix[*arr].tr - Matrix[*arr.reverse].tr).abs

Where arr is an array of depth 2 with length n and each sub-array is also of length n e.g. [[a,b],[c,d]].

Solution 3:[3]

Sidenote: NB I am posting this as an answer, not a comment, for the sake of formatting; it should not be upvoted.

The more ruby idiomatic version of the snippet you have posted would be:

def diagonal_difference(a)
  a.each.with_object([0, 0]).with_index do |(e, left_right), idx|
    left_right[0] += array[idx]
    right_left[1] += array[-idx-1]
  end.reduce(:-).abs
end

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2
Solution 3