AlgoVerse

Maze solving (backtracking)

Find a way from the top-left to the bottom-right corner: go forward, and at every dead end mark it and back up.

The maze is a table: 0 is an open cell and 1 a wall. Start at the top-left corner and try right, down, left and up in turn:

Read the full explanation ↓
Input:
grid 5×5PDF export

A 5×5 maze; the branch on the right is tried first and hits a dead end (x), then the way along the bottom reaches the exit (o).

  1. def solve_maze(grid):
  2. # 0 is open and 1 is a wall; find a way from the top-left to the bottom-right corner.
  3. rows, cols = len(grid), len(grid[0])
  4. board = [["█" if cell else "·" for cell in row] for row in grid]
  5. if grid[0][0] or grid[rows - 1][cols - 1]:
  6. return False
  7. return walk(board, 0, 0, rows, cols)
  8. def walk(board, r, c, rows, cols):
  9. if r < 0 or r >= rows or c < 0 or c >= cols or board[r][c] != "·":
  10. return False
  11. board[r][c] = "o"
  12. if r == rows - 1 and c == cols - 1:
  13. return True
  14. for dr, dc in [(0, 1), (1, 0), (0, -1), (-1, 0)]:
  15. if walk(board, r + dr, c + dc, rows, cols):
  16. return True
  17. board[r][c] = "x"
  18. return False

Invariant: The o cells always form one connected path from the start to the current cell, and each cell is entered at most once.

Start

r—
c—

The table is still empty.

Recursion tree

Filled orange = running call · Orange outline = still on the stack · Grey = finished

Local variables

Orange = changed in this step

grid list

[0, 0, 0, 1, 0][1, 1, 0, 1, 0][0, 0, 0, 0, 0][0, 1, 1, 1, 1][0, 0, 0, 0, 0]

Call stack

  1. solve_maze()line 1
Step 1 of 230
Black = enter · Orange = key stepenter: 0/17 · dead_end: 0/4 · reached: 0/1
    Explanation

    The idea

    The maze is a table: 0 is an open cell and 1 a wall. Start at the top-left corner and try right, down, left and up in turn:

    • if the next cell is open and not seen yet, enter it (o);
    • if no way forward is left from a cell, mark it as a dead end (x) and step back.

    This is depth-first search on the graph of cells; the call stack is the current path.

    Cost

    Each cell is entered at most once: O(rows × cols). The path found is not necessarily the shortest; for that, use breadth-first search.

    What to watch in the trace

    • The table is the maze: █ walls, o the current path and x the dead ends. The call tree shows the branches tried.