Search code examples
pythonmaze

Passing through a 2d binary array recursively and counting the number of "1's" to pass through


I'm attempting to learn programming and one concept I'm really struggling to understand is recursion.

Edit: Below is a link to an image of the actual question which explains the instructions a lot better. I think my explanation wasn't the best.

Instructions

I'm trying to write a program using recursion on python that takes a 2 dimensional binary array of A[0,...,n-1][0,...,n-1] and returns the minimum number of "1's" that must be passed through to reach the end point. The start point is A[0][0] and the end point is A[n-1][n-1]. You can only move one cell at a time, by either moving one cell to the right or one cell down. The array contains only 0's and 1's. It is similar to a maze where one must pass through the 0's, and the 1's act as a wall but here one can and will likely need to travel through a few 1's. The output will be the minimum number of 1's required to pass through to reach the end point.

I'm not sure if this is the right approach. I think I may be better off with the 1 function. I also can't seem to figure out how to count the number of dangerous zones that must be passed through. I think you may notice that I am new to this and I would be grateful if someone could lead me in the right direction.

def minCellsTravel(grid):

    gridWidth = len(grid[0])
    gridHeight = len(grid)

    def helperFn(row, col):

            # if we already reached the rightmost end
            if row == gridHeight-1 and col == gridWidth-1:
                    return grid[row][col]

            start = grid[row][col]
            downMove = None
            if row < gridHeight - 1:
                    downMove = start + helperFn(row + 1, col)

            rightMove = None
            if col < gridWidth - 1:
                    rightMove = start + helperFn(row, col + 1)

            if rightMove and downMove:
                    return min(rightMove, downMove)
            elif rightMove:
                    return rightMove
            else:
                    return downMove

Solution

  • Something like this should do the trick

    def solve(row, col, A):
    
        if (row == A.shape[0] - 1) and (col == A.shape[1] - 1):
            return A[row][col]
        if (row >= A.shape[0]) or (col >= A.shape[1]):
            return A.shape[0] + A.shape[1]
    
        left = solve(row + 1, col, A)
        right = solve(row, col + 1, A)
        best_path = min(right, left)
    
        return best_path + A[row][col]
    

    The idea is that at each cell you can either go right or down, and the best solution starting on this cell is the best solution starting on the cell to your right or the best solution starting on the cell to your left. Take the best one plus the value of the current cell and you have the solution starting on the current cell.

    Although is possible to solve this problem with recursion, dynamic programming is more efficient is this kind of problems, take a look at it if you're curious.