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))
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.
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.
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)
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)
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))
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.
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.
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)
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)