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