|
| 1 | +def solve_maze(maze: list) -> bool: |
| 2 | + """ |
| 3 | + This method solves rat in maze algorithm. |
| 4 | + In this problem we have n by n matrix and we have start point and end point |
| 5 | + we want to go from source to distination. In this matrix 0 are block paths |
| 6 | + 1 are open paths we can use. |
| 7 | + Parameters : |
| 8 | + maze(2D matrix) : maze |
| 9 | + Returns: |
| 10 | + Return: True is maze has a solution or False if it does not. |
| 11 | + >>> maze = [[0, 1, 0, 1, 1], |
| 12 | + ... [0, 0, 0, 0, 0], |
| 13 | + ... [1, 0, 1, 0, 1], |
| 14 | + ... [0, 0, 1, 0, 0], |
| 15 | + ... [1, 0, 0, 1, 0]] |
| 16 | + >>> solve_maze(maze) |
| 17 | + [1, 0, 0, 0, 0] |
| 18 | + [1, 1, 1, 1, 0] |
| 19 | + [0, 0, 0, 1, 0] |
| 20 | + [0, 0, 0, 1, 1] |
| 21 | + [0, 0, 0, 0, 1] |
| 22 | + True |
| 23 | +
|
| 24 | + >>> maze = [[0, 1, 0, 1, 1], |
| 25 | + ... [0, 0, 0, 0, 0], |
| 26 | + ... [0, 0, 0, 0, 1], |
| 27 | + ... [0, 0, 0, 0, 0], |
| 28 | + ... [0, 0, 0, 0, 0]] |
| 29 | + >>> solve_maze(maze) |
| 30 | + [1, 0, 0, 0, 0] |
| 31 | + [1, 0, 0, 0, 0] |
| 32 | + [1, 0, 0, 0, 0] |
| 33 | + [1, 0, 0, 0, 0] |
| 34 | + [1, 1, 1, 1, 1] |
| 35 | + True |
| 36 | +
|
| 37 | + >>> maze = [[0, 0, 0], |
| 38 | + ... [0, 1, 0], |
| 39 | + ... [1, 0, 0]] |
| 40 | + >>> solve_maze(maze) |
| 41 | + [1, 1, 1] |
| 42 | + [0, 0, 1] |
| 43 | + [0, 0, 1] |
| 44 | + True |
| 45 | +
|
| 46 | + >>> maze = [[0, 1, 0], |
| 47 | + ... [0, 1, 0], |
| 48 | + ... [1, 0, 0]] |
| 49 | + >>> solve_maze(maze) |
| 50 | + Solution does not exists! |
| 51 | + False |
| 52 | +
|
| 53 | + >>> maze = [[0, 1], |
| 54 | + ... [1, 0]] |
| 55 | + >>> solve_maze(maze) |
| 56 | + Solution does not exists! |
| 57 | + False |
| 58 | + """ |
| 59 | + size = len(maze) |
| 60 | + # We need to create solution object to save path. |
| 61 | + solutions = [[0 for _ in range(size)] for _ in range(size)] |
| 62 | + solved = run_maze(maze, 0, 0, solutions) |
| 63 | + if solved: |
| 64 | + print("\n".join(str(row) for row in solutions)) |
| 65 | + else: |
| 66 | + print("Solution does not exists!") |
| 67 | + return solved |
| 68 | + |
| 69 | + |
| 70 | +def run_maze(maze, i, j, solutions): |
| 71 | + """ |
| 72 | + This method is recursive method which starts from i and j |
| 73 | + and goes with 4 direction option up, down, left, right |
| 74 | + if path found to destination it breaks and return True |
| 75 | + otherwise False |
| 76 | + Parameters: |
| 77 | + maze(2D matrix) : maze |
| 78 | + i, j : coordinates of matrix |
| 79 | + solutions(2D matrix) : solutions |
| 80 | + Returns: |
| 81 | + Boolean if path is found True, Otherwise False. |
| 82 | + """ |
| 83 | + size = len(maze) |
| 84 | + # Final check point. |
| 85 | + if i == j == (size - 1): |
| 86 | + solutions[i][j] = 1 |
| 87 | + return True |
| 88 | + |
| 89 | + lower_flag = (not (i < 0)) and (not (j < 0)) # Check lower bounds |
| 90 | + upper_flag = (i < size) and (j < size) # Check upper bounds |
| 91 | + |
| 92 | + if lower_flag and upper_flag: |
| 93 | + # check for already visited and block points. |
| 94 | + block_flag = (not (solutions[i][j])) and (not (maze[i][j])) |
| 95 | + if block_flag: |
| 96 | + # check visited |
| 97 | + solutions[i][j] = 1 |
| 98 | + |
| 99 | + # check for directions |
| 100 | + if (run_maze(maze, i + 1, j, solutions) or |
| 101 | + run_maze(maze, i, j + 1, solutions) or |
| 102 | + run_maze(maze, i - 1, j, solutions) or |
| 103 | + run_maze(maze, i, j - 1, solutions)): |
| 104 | + return True |
| 105 | + |
| 106 | + solutions[i][j] = 0 |
| 107 | + return False |
| 108 | + |
| 109 | + |
| 110 | +if __name__ == "__main__": |
| 111 | + import doctest |
| 112 | + |
| 113 | + doctest.testmod() |
0 commit comments