I am solving a problem which involves traversing a n x m matrix
in a zigzag fashion, where n and m
can be same number or different numbers, i.e. we will have a square or rectangular matrix.
To solve this problem, I have a main method which will traverse the matrix; and within this main method, I create and call on moveDiagonallyUpwards
and moveDiagonallyDownwards
methods to move in the zigzag way.
The problem I am having is that when I pass row
and col
as arguments from the main method into these two other methods, and inside these methods I update row and col, e.g. =1 or -= 1.
These changes DO NOT reflect in the main method, when I return to the main method. And I do understand why this is the case.
So my challenge is, how can I pass back the updated row
and col
to the main method? I thought of using a global class
to achieve the above.
My idea is to create a separate class to hold these variables like the below, but I am having problems with calling and using these global row and col
in my main method.
Any ideas how to adjust the row and col
in main method to achieve the above? Thanks!
array = [
[1, 3, 4, 10],
[2, 5, 9, 11],
[6, 8, 12, 15],
[7, 13, 14, 16]
]
class matrixMovement:
def __init__(self,row=0,col=0,output=[]):
self.row = row
self.col = col
self.output = output
#Main Method
def zigzagTraverse(array):
output.append(array[row][col])
while array.row<= len(array)-1 or array.col<= len(array[0])-1:
if array.row< len(array)-1:
array.row = 1
output.append(array[row][col])
diagonalUp(row,col,array,output)
if col < len(array[0])-1:
col = 1
output.append(array[row][col])
diagonalDown(row,col,array,output)
return output
def diagonalUp(row,col,array,output):
while row > 0 and col< len(array[0])-1:
row -= 1
col = 1
output.append(array[row][col])
return matrixMovemenet(row,col,output)
def diagonalDown(row,col,array,output):
while row<len(array)-1 and col > 0:
col-= 1
row = 1
output.append(array[row][col])
return matrixMovemenet(row,col,output)
CodePudding user response:
You have a few problems. One is local scope. Another is using the return
statement but doing nothing with the object returned.
There are a few ways to solve this. One is to ignore the local variables and just create an object from matrixMovement
and utilize the fact that it's mutable.
class MatrixMovement:
def __init__(self, row=0, col=0, output=None):
# I modified this to avoid the mutable default
if output is None:
output = []
self.row = row
self.col = col
self.output = output
# Main Method
def zigzag_traverse(array):
# this is the object we will be mutating
obj = MatrixMovement()
obj.output.append(array[obj.row][obj.col])
while obj.row <= len(array) - 1 or obj.col <= len(array[0]) - 1:
if obj.row < len(array) - 1:
obj.row = 1
obj.output.append(array[obj.row][obj.col])
diagonal_up(obj, array)
if obj.col < len(array[0]) - 1:
obj.col = 1
obj.output.append(array[obj.row][obj.col])
diagonal_down(obj, array)
# without this condition the loop will never break
if obj.row == len(array) - 1 and obj.col == len(array[0]) - 1:
break
return obj.output
def diagonal_up(obj, array):
# since we are passing in a mutable object
# anything attribute we change on it
# will be reflected on the object from the call site
while obj.row > 0 and obj.col < len(array[0]) - 1:
obj.row -= 1
obj.col = 1
obj.output.append(array[obj.row][obj.col])
def diagonal_down(obj, array):
# the same rules as diagonal_up
while obj.row < len(array) - 1 and obj.col > 0:
obj.col -= 1
obj.row = 1
obj.output.append(array[obj.row][obj.col])