Skip to content

Commit c16d2f8

Browse files
Muhammadummerrpre-commit-ci[bot]cclauss
authored
UPDATED rat_in_maze.py (TheAlgorithms#9148)
* UPDATED rat_in_maze.py * Update reddit.py in Webprogramming b/c it was causing error in pre-commit tests while raising PR. * UPDATED rat_in_maze.py * fixed return type to only maze,otherwise raise valueError. * fixed whitespaces error,improved matrix visual. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * updated. * Try * updated * updated * Apply suggestions from code review --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Christian Clauss <[email protected]>
1 parent d580625 commit c16d2f8

File tree

1 file changed

+130
-51
lines changed

1 file changed

+130
-51
lines changed

Diff for: backtracking/rat_in_maze.py

+130-51
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,197 @@
11
from __future__ import annotations
22

33

4-
def solve_maze(maze: list[list[int]]) -> bool:
4+
def solve_maze(
5+
maze: list[list[int]],
6+
source_row: int,
7+
source_column: int,
8+
destination_row: int,
9+
destination_column: int,
10+
) -> list[list[int]]:
511
"""
612
This method solves the "rat in maze" problem.
7-
In this problem we have some n by n matrix, a start point and an end point.
8-
We want to go from the start to the end. In this matrix zeroes represent walls
9-
and ones paths we can use.
1013
Parameters :
11-
maze(2D matrix) : maze
14+
- maze: A two dimensional matrix of zeros and ones.
15+
- source_row: The row index of the starting point.
16+
- source_column: The column index of the starting point.
17+
- destination_row: The row index of the destination point.
18+
- destination_column: The column index of the destination point.
1219
Returns:
13-
Return: True if the maze has a solution or False if it does not.
20+
- solution: A 2D matrix representing the solution path if it exists.
21+
Raises:
22+
- ValueError: If no solution exists or if the source or
23+
destination coordinates are invalid.
24+
Description:
25+
This method navigates through a maze represented as an n by n matrix,
26+
starting from a specified source cell and
27+
aiming to reach a destination cell.
28+
The maze consists of walls (1s) and open paths (0s).
29+
By providing custom row and column values, the source and destination
30+
cells can be adjusted.
1431
>>> maze = [[0, 1, 0, 1, 1],
1532
... [0, 0, 0, 0, 0],
1633
... [1, 0, 1, 0, 1],
1734
... [0, 0, 1, 0, 0],
1835
... [1, 0, 0, 1, 0]]
19-
>>> solve_maze(maze)
20-
[1, 0, 0, 0, 0]
21-
[1, 1, 1, 1, 0]
22-
[0, 0, 0, 1, 0]
23-
[0, 0, 0, 1, 1]
24-
[0, 0, 0, 0, 1]
25-
True
36+
>>> solve_maze(maze,0,0,len(maze)-1,len(maze)-1) # doctest: +NORMALIZE_WHITESPACE
37+
[[0, 1, 1, 1, 1],
38+
[0, 0, 0, 0, 1],
39+
[1, 1, 1, 0, 1],
40+
[1, 1, 1, 0, 0],
41+
[1, 1, 1, 1, 0]]
42+
43+
Note:
44+
In the output maze, the zeros (0s) represent one of the possible
45+
paths from the source to the destination.
2646
2747
>>> maze = [[0, 1, 0, 1, 1],
2848
... [0, 0, 0, 0, 0],
2949
... [0, 0, 0, 0, 1],
3050
... [0, 0, 0, 0, 0],
3151
... [0, 0, 0, 0, 0]]
32-
>>> solve_maze(maze)
33-
[1, 0, 0, 0, 0]
34-
[1, 0, 0, 0, 0]
35-
[1, 0, 0, 0, 0]
36-
[1, 0, 0, 0, 0]
37-
[1, 1, 1, 1, 1]
38-
True
52+
>>> solve_maze(maze,0,0,len(maze)-1,len(maze)-1) # doctest: +NORMALIZE_WHITESPACE
53+
[[0, 1, 1, 1, 1],
54+
[0, 1, 1, 1, 1],
55+
[0, 1, 1, 1, 1],
56+
[0, 1, 1, 1, 1],
57+
[0, 0, 0, 0, 0]]
3958
4059
>>> maze = [[0, 0, 0],
4160
... [0, 1, 0],
4261
... [1, 0, 0]]
43-
>>> solve_maze(maze)
44-
[1, 1, 1]
45-
[0, 0, 1]
46-
[0, 0, 1]
47-
True
62+
>>> solve_maze(maze,0,0,len(maze)-1,len(maze)-1) # doctest: +NORMALIZE_WHITESPACE
63+
[[0, 0, 0],
64+
[1, 1, 0],
65+
[1, 1, 0]]
4866
49-
>>> maze = [[0, 1, 0],
67+
>>> maze = [[1, 0, 0],
5068
... [0, 1, 0],
5169
... [1, 0, 0]]
52-
>>> solve_maze(maze)
53-
No solution exists!
54-
False
70+
>>> solve_maze(maze,0,1,len(maze)-1,len(maze)-1) # doctest: +NORMALIZE_WHITESPACE
71+
[[1, 0, 0],
72+
[1, 1, 0],
73+
[1, 1, 0]]
74+
75+
>>> maze = [[1, 1, 0, 0, 1, 0, 0, 1],
76+
... [1, 0, 1, 0, 0, 1, 1, 1],
77+
... [0, 1, 0, 1, 0, 0, 1, 0],
78+
... [1, 1, 1, 0, 0, 1, 0, 1],
79+
... [0, 1, 0, 0, 1, 0, 1, 1],
80+
... [0, 0, 0, 1, 1, 1, 0, 1],
81+
... [0, 1, 0, 1, 0, 1, 1, 1],
82+
... [1, 1, 0, 0, 0, 0, 0, 1]]
83+
>>> solve_maze(maze,0,2,len(maze)-1,2) # doctest: +NORMALIZE_WHITESPACE
84+
[[1, 1, 0, 0, 1, 1, 1, 1],
85+
[1, 1, 1, 0, 0, 1, 1, 1],
86+
[1, 1, 1, 1, 0, 1, 1, 1],
87+
[1, 1, 1, 0, 0, 1, 1, 1],
88+
[1, 1, 0, 0, 1, 1, 1, 1],
89+
[1, 1, 0, 1, 1, 1, 1, 1],
90+
[1, 1, 0, 1, 1, 1, 1, 1],
91+
[1, 1, 0, 1, 1, 1, 1, 1]]
92+
>>> maze = [[1, 0, 0],
93+
... [0, 1, 1],
94+
... [1, 0, 1]]
95+
>>> solve_maze(maze,0,1,len(maze)-1,len(maze)-1)
96+
Traceback (most recent call last):
97+
...
98+
ValueError: No solution exists!
99+
100+
>>> maze = [[0, 0],
101+
... [1, 1]]
102+
>>> solve_maze(maze,0,0,len(maze)-1,len(maze)-1)
103+
Traceback (most recent call last):
104+
...
105+
ValueError: No solution exists!
55106
56107
>>> maze = [[0, 1],
57108
... [1, 0]]
58-
>>> solve_maze(maze)
59-
No solution exists!
60-
False
109+
>>> solve_maze(maze,2,0,len(maze)-1,len(maze)-1)
110+
Traceback (most recent call last):
111+
...
112+
ValueError: Invalid source or destination coordinates
113+
114+
>>> maze = [[1, 0, 0],
115+
... [0, 1, 0],
116+
... [1, 0, 0]]
117+
>>> solve_maze(maze,0,1,len(maze),len(maze)-1)
118+
Traceback (most recent call last):
119+
...
120+
ValueError: Invalid source or destination coordinates
61121
"""
62122
size = len(maze)
123+
# Check if source and destination coordinates are Invalid.
124+
if not (0 <= source_row <= size - 1 and 0 <= source_column <= size - 1) or (
125+
not (0 <= destination_row <= size - 1 and 0 <= destination_column <= size - 1)
126+
):
127+
raise ValueError("Invalid source or destination coordinates")
63128
# We need to create solution object to save path.
64-
solutions = [[0 for _ in range(size)] for _ in range(size)]
65-
solved = run_maze(maze, 0, 0, solutions)
129+
solutions = [[1 for _ in range(size)] for _ in range(size)]
130+
solved = run_maze(
131+
maze, source_row, source_column, destination_row, destination_column, solutions
132+
)
66133
if solved:
67-
print("\n".join(str(row) for row in solutions))
134+
return solutions
68135
else:
69-
print("No solution exists!")
70-
return solved
136+
raise ValueError("No solution exists!")
71137

72138

73-
def run_maze(maze: list[list[int]], i: int, j: int, solutions: list[list[int]]) -> bool:
139+
def run_maze(
140+
maze: list[list[int]],
141+
i: int,
142+
j: int,
143+
destination_row: int,
144+
destination_column: int,
145+
solutions: list[list[int]],
146+
) -> bool:
74147
"""
75148
This method is recursive starting from (i, j) and going in one of four directions:
76149
up, down, left, right.
77150
If a path is found to destination it returns True otherwise it returns False.
78-
Parameters:
79-
maze(2D matrix) : maze
151+
Parameters
152+
maze: A two dimensional matrix of zeros and ones.
80153
i, j : coordinates of matrix
81-
solutions(2D matrix) : solutions
154+
solutions: A two dimensional matrix of solutions.
82155
Returns:
83156
Boolean if path is found True, Otherwise False.
84157
"""
85158
size = len(maze)
86159
# Final check point.
87-
if i == j == (size - 1):
88-
solutions[i][j] = 1
160+
if i == destination_row and j == destination_column and maze[i][j] == 0:
161+
solutions[i][j] = 0
89162
return True
90163

91164
lower_flag = (not i < 0) and (not j < 0) # Check lower bounds
92165
upper_flag = (i < size) and (j < size) # Check upper bounds
93166

94167
if lower_flag and upper_flag:
95168
# check for already visited and block points.
96-
block_flag = (not solutions[i][j]) and (not maze[i][j])
169+
block_flag = (solutions[i][j]) and (not maze[i][j])
97170
if block_flag:
98171
# check visited
99-
solutions[i][j] = 1
172+
solutions[i][j] = 0
100173

101174
# check for directions
102175
if (
103-
run_maze(maze, i + 1, j, solutions)
104-
or run_maze(maze, i, j + 1, solutions)
105-
or run_maze(maze, i - 1, j, solutions)
106-
or run_maze(maze, i, j - 1, solutions)
176+
run_maze(maze, i + 1, j, destination_row, destination_column, solutions)
177+
or run_maze(
178+
maze, i, j + 1, destination_row, destination_column, solutions
179+
)
180+
or run_maze(
181+
maze, i - 1, j, destination_row, destination_column, solutions
182+
)
183+
or run_maze(
184+
maze, i, j - 1, destination_row, destination_column, solutions
185+
)
107186
):
108187
return True
109188

110-
solutions[i][j] = 0
189+
solutions[i][j] = 1
111190
return False
112191
return False
113192

114193

115194
if __name__ == "__main__":
116195
import doctest
117196

118-
doctest.testmod()
197+
doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)

0 commit comments

Comments
 (0)