-
-
Notifications
You must be signed in to change notification settings - Fork 46.9k
UPDATED rat_in_maze.py #9148
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UPDATED rat_in_maze.py #9148
Changes from 15 commits
9450821
9a1d65f
741bb72
1b2a9e6
726bc5c
d9e1956
49e6dee
b59a85d
cedaf35
775d6cd
c740da3
591c098
9c89c79
1539b6f
e169d07
8013870
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,81 +1,155 @@ | ||
from __future__ import annotations | ||
|
||
|
||
def solve_maze(maze: list[list[int]]) -> bool: | ||
def solve_maze( | ||
maze: list[list[int]], | ||
source_row: int, | ||
source_column: int, | ||
destination_row: int, | ||
destination_column: int, | ||
) -> list[list[int]]: | ||
""" | ||
This method solves the "rat in maze" problem. | ||
In this problem we have some n by n matrix, a start point and an end point. | ||
We want to go from the start to the end. In this matrix zeroes represent walls | ||
and ones paths we can use. | ||
Parameters : | ||
maze(2D matrix) : maze | ||
- maze(2D matrix) : maze | ||
- source_row (int): The row index of the starting point. | ||
- source_column (int): The column index of the starting point. | ||
- destination_row (int): The row index of the destination point. | ||
- destination_column (int): The column index of the destination point. | ||
Returns: | ||
Return: True if the maze has a solution or False if it does not. | ||
- solution (list[list[int]]): A 2D matrix representing the solution path | ||
if it exists. | ||
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Raises: | ||
- ValueError: If no solution exists or if the source or | ||
destination coordinates are invalid. | ||
Description: | ||
This method navigates through a maze represented as an n by n matrix, | ||
starting from a specified source cell and | ||
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
|
||
aiming to reach a destination cell. | ||
The maze consists of walls (1s) and open paths (0s). | ||
By providing custom row and column values, the source and destination | ||
cells can be adjusted. | ||
>>> maze = [[0, 1, 0, 1, 1], | ||
... [0, 0, 0, 0, 0], | ||
... [1, 0, 1, 0, 1], | ||
... [0, 0, 1, 0, 0], | ||
... [1, 0, 0, 1, 0]] | ||
>>> solve_maze(maze) | ||
[1, 0, 0, 0, 0] | ||
[1, 1, 1, 1, 0] | ||
[0, 0, 0, 1, 0] | ||
[0, 0, 0, 1, 1] | ||
[0, 0, 0, 0, 1] | ||
True | ||
>>> solve_maze(maze,0,0,len(maze)-1,len(maze)-1) # doctest: +NORMALIZE_WHITESPACE | ||
[[0, 1, 1, 1, 1], | ||
[0, 0, 0, 0, 1], | ||
[1, 1, 1, 0, 1], | ||
[1, 1, 1, 0, 0], | ||
[1, 1, 1, 1, 0]] | ||
|
||
Note: | ||
In the output maze, the zeros (0s) represent one of the possible | ||
paths from the source to the destination. | ||
|
||
>>> maze = [[0, 1, 0, 1, 1], | ||
... [0, 0, 0, 0, 0], | ||
... [0, 0, 0, 0, 1], | ||
... [0, 0, 0, 0, 0], | ||
... [0, 0, 0, 0, 0]] | ||
>>> solve_maze(maze) | ||
[1, 0, 0, 0, 0] | ||
[1, 0, 0, 0, 0] | ||
[1, 0, 0, 0, 0] | ||
[1, 0, 0, 0, 0] | ||
[1, 1, 1, 1, 1] | ||
True | ||
>>> solve_maze(maze,0,0,len(maze)-1,len(maze)-1) # doctest: +NORMALIZE_WHITESPACE | ||
[[0, 1, 1, 1, 1], | ||
[0, 1, 1, 1, 1], | ||
[0, 1, 1, 1, 1], | ||
[0, 1, 1, 1, 1], | ||
[0, 0, 0, 0, 0]] | ||
|
||
>>> maze = [[0, 0, 0], | ||
... [0, 1, 0], | ||
... [1, 0, 0]] | ||
>>> solve_maze(maze) | ||
[1, 1, 1] | ||
[0, 0, 1] | ||
[0, 0, 1] | ||
True | ||
>>> solve_maze(maze,0,0,len(maze)-1,len(maze)-1) # doctest: +NORMALIZE_WHITESPACE | ||
[[0, 0, 0], | ||
[1, 1, 0], | ||
[1, 1, 0]] | ||
|
||
>>> maze = [[0, 1, 0], | ||
>>> maze = [[1, 0, 0], | ||
... [0, 1, 0], | ||
... [1, 0, 0]] | ||
>>> solve_maze(maze) | ||
No solution exists! | ||
False | ||
>>> solve_maze(maze,0,1,len(maze)-1,len(maze)-1) # doctest: +NORMALIZE_WHITESPACE | ||
[[1, 0, 0], | ||
[1, 1, 0], | ||
[1, 1, 0]] | ||
|
||
>>> maze = [[1, 1, 0, 0, 1, 0, 0, 1], | ||
... [1, 0, 1, 0, 0, 1, 1, 1], | ||
... [0, 1, 0, 1, 0, 0, 1, 0], | ||
... [1, 1, 1, 0, 0, 1, 0, 1], | ||
... [0, 1, 0, 0, 1, 0, 1, 1], | ||
... [0, 0, 0, 1, 1, 1, 0, 1], | ||
... [0, 1, 0, 1, 0, 1, 1, 1], | ||
... [1, 1, 0, 0, 0, 0, 0, 1]] | ||
>>> solve_maze(maze,0,2,len(maze)-1,2) # doctest: +NORMALIZE_WHITESPACE | ||
[[1, 1, 0, 0, 1, 1, 1, 1], | ||
[1, 1, 1, 0, 0, 1, 1, 1], | ||
[1, 1, 1, 1, 0, 1, 1, 1], | ||
[1, 1, 1, 0, 0, 1, 1, 1], | ||
[1, 1, 0, 0, 1, 1, 1, 1], | ||
[1, 1, 0, 1, 1, 1, 1, 1], | ||
[1, 1, 0, 1, 1, 1, 1, 1], | ||
[1, 1, 0, 1, 1, 1, 1, 1]] | ||
>>> maze = [[1, 0, 0], | ||
... [0, 1, 1], | ||
... [1, 0, 1]] | ||
>>> solve_maze(maze,0,1,len(maze)-1,len(maze)-1) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: No solution exists! | ||
|
||
>>> maze = [[0, 0], | ||
... [1, 1]] | ||
>>> solve_maze(maze,0,0,len(maze)-1,len(maze)-1) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: No solution exists! | ||
|
||
>>> maze = [[0, 1], | ||
... [1, 0]] | ||
>>> solve_maze(maze) | ||
No solution exists! | ||
False | ||
>>> solve_maze(maze,2,0,len(maze)-1,len(maze)-1) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: Invalid source or destination coordinates | ||
|
||
>>> maze = [[1, 0, 0], | ||
... [0, 1, 0], | ||
... [1, 0, 0]] | ||
>>> solve_maze(maze,0,1,len(maze),len(maze)-1) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: Invalid source or destination coordinates | ||
""" | ||
size = len(maze) | ||
# Check if source and destination coordinates are Invalid. | ||
if not (0 <= source_row <= size - 1 and 0 <= source_column <= size - 1) or ( | ||
not (0 <= destination_row <= size - 1 and 0 <= destination_column <= size - 1) | ||
): | ||
raise ValueError("Invalid source or destination coordinates") | ||
# We need to create solution object to save path. | ||
solutions = [[0 for _ in range(size)] for _ in range(size)] | ||
solved = run_maze(maze, 0, 0, solutions) | ||
solutions = [[1 for _ in range(size)] for _ in range(size)] | ||
solved = run_maze( | ||
maze, source_row, source_column, destination_row, destination_column, solutions | ||
) | ||
if solved: | ||
print("\n".join(str(row) for row in solutions)) | ||
return solutions | ||
else: | ||
print("No solution exists!") | ||
return solved | ||
raise ValueError("No solution exists!") | ||
|
||
|
||
def run_maze(maze: list[list[int]], i: int, j: int, solutions: list[list[int]]) -> bool: | ||
def run_maze( | ||
maze: list[list[int]], | ||
i: int, | ||
j: int, | ||
destination_row: int, | ||
destination_column: int, | ||
solutions: list[list[int]], | ||
) -> bool: | ||
""" | ||
This method is recursive starting from (i, j) and going in one of four directions: | ||
up, down, left, right. | ||
If a path is found to destination it returns True otherwise it returns False. | ||
Parameters: | ||
Parameters | ||
maze(2D matrix) : maze | ||
i, j : coordinates of matrix | ||
solutions(2D matrix) : solutions | ||
cclauss marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
@@ -84,35 +158,41 @@ def run_maze(maze: list[list[int]], i: int, j: int, solutions: list[list[int]]) | |
""" | ||
size = len(maze) | ||
# Final check point. | ||
if i == j == (size - 1): | ||
solutions[i][j] = 1 | ||
if i == destination_row and j == destination_column and maze[i][j] == 0: | ||
solutions[i][j] = 0 | ||
return True | ||
|
||
lower_flag = (not i < 0) and (not j < 0) # Check lower bounds | ||
upper_flag = (i < size) and (j < size) # Check upper bounds | ||
|
||
if lower_flag and upper_flag: | ||
# check for already visited and block points. | ||
block_flag = (not solutions[i][j]) and (not maze[i][j]) | ||
block_flag = (solutions[i][j]) and (not maze[i][j]) | ||
if block_flag: | ||
# check visited | ||
solutions[i][j] = 1 | ||
solutions[i][j] = 0 | ||
|
||
# check for directions | ||
if ( | ||
run_maze(maze, i + 1, j, solutions) | ||
or run_maze(maze, i, j + 1, solutions) | ||
or run_maze(maze, i - 1, j, solutions) | ||
or run_maze(maze, i, j - 1, solutions) | ||
run_maze(maze, i + 1, j, destination_row, destination_column, solutions) | ||
or run_maze( | ||
maze, i, j + 1, destination_row, destination_column, solutions | ||
) | ||
or run_maze( | ||
maze, i - 1, j, destination_row, destination_column, solutions | ||
) | ||
or run_maze( | ||
maze, i, j - 1, destination_row, destination_column, solutions | ||
) | ||
): | ||
return True | ||
|
||
solutions[i][j] = 0 | ||
solutions[i][j] = 1 | ||
return False | ||
return False | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() | ||
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does this work?!? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, it's working on my local machine, but it's not working on the build test. That's why I added '# doctest: +NORMALIZE_WHITESPACE' to each test. |
Uh oh!
There was an error while loading. Please reload this page.