Diagonal difference in Python

Question:

I am working on a HackerRank problem and I don’t understand some of the logic:

if (i == j):
    left += a[i][j]

The above is saying if the row/column indices are the same([1,1], [2,2], [3,3]), append value found at those coordinates to the list ‘left’

I don’t understand the logic in the code below. To me it looks like it’s saying append values found at the coordinates where row index + column index = 3 (n-1) but I don’t think that’s right. What would the code below translate to?

if (i + j) == (n - 1):
    right += a[i][j]

Below is the function with sample inputs a and n.

a = [[ 1, 2, 3, 4 ],
     [ 5, 6, 7, 8 ],
     [ 1, 2, 3, 4 ],
     [ 5, 6, 7, 9 ]]

n = 4
def xsum(a, n):
    left = 0
    right = 0
    for i in range(0, n):
        for j in range(0, n):
            if (i == j):
                left += a[i][j]
            if (i + j) == (n - 1):
                right += a[i][j]
    return (abs(left-right))
Asked By: codereyes

||

Answers:

This looks an awful lot like it’s working too hard.

If we want to calculate that "left" diagonal.

a = [[ 1, 2, 3, 4 ],
     [ 5, 6, 7, 8 ],
     [ 1, 2, 3, 4 ],
     [ 5, 6, 7, 9 ]]

left = []
for i in range(0, 4):
    left.append(a[i][i])

Or:

left = [a[i][i] for i in range(0, 4)]

To find the "right" diagonal.

right = [a[i][3 - i] for i in range(0, 4)]

If we need to see how this generates a set of indices to index into a, we can with the following:

>>> [(i, 3 - i) for i in range(0, 4)]
[(0, 3), (1, 2), (2, 1), (3, 0)]

Which yields: [4, 7, 2, 5]. If you need it reversed.

right = [a[3 - i][i] for i in range(0, 4)]

This yields: [5, 2, 7, 4].

If we need the sum of the left diagonal, we just need to use the sum function: left_sum = sum(left)

I’ve written these examples specifically for a 4×4 matrix. It should be straightforward to generalize this for larger or smaller matrices.

Answered By: Chris

What would the code below translate to?

The code leverages the fact that an element is on the right diagonal if and only if the row and column indices sum to n - 1. It then adds the value at the given (i, j) pair to right.

This can be visualized using the following matrix: each entry is the sum of its row and column index:

print([[i + j for i in range(4)] for j in range(4)])
#[[0, 1, 2, 3],
# [1, 2, 3, 4],
# [2, 3, 4, 5], 
# [3, 4, 5, 6]]
# (notice that the n - 1 == 3, and the 3s are only on the antidiagonal!)

This is a question about correctness, which is distinct from efficiency. If you’re wondering whether this code is efficient, the answer is no: see Chris’s answer.

Answered By: BrokenBenchmark
def diagonalDifference(arr):

    mat = len(arr[0]) #type of matrix e.g(3by3)
    left_sum = 0
    right_sum =0
    k =mat-1 #rightmost element accessor 

    for i in range(mat):
        left_sum += arr[i][i] 

    for j in range(mat):
        right_sum += arr[j][k]
        k-=1

    return abs(right_sum - left_sum)
Answered By: Fabian Umeh

The solution is as good as how many steps/operation You are going to reduce here…. those are trivial…
What worries me is that why experts from hackerrank do not respect the PEP8 standard. The diagonalDifference should be called diagonal_difference ;(((

https://legacy.python.org/dev/peps/pep-0008/#id42

Function Names

Function names should be lowercase, with words separated by underscores as necessary to improve readability.

mixedCase is allowed only in contexts where that’s already the prevailing style (e.g. threading.py), to retain backwards compatibility.

Soo, are they in "the prevailing style (e.g. threading.py), to retain backwards compatibility" ???
Come one guys… No they’re not!!!

def diagonalDifference(arr):
    left_diagonal = 0
    right_diagonal = 0
    size = len(arr)
    size_including_zero = size - 1
    for i in range(0, size):
        left_diagonal += arr[i][i]
        right_diagonal += arr[i][size_including_zero-i]
    
    return abs(left_diagonal-right_diagonal)
Answered By: Leszek Kolacz
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.