Program to find out the shortest path to reach the goal in Python

Finding the shortest path in a grid is a classic problem that can be solved using Breadth-First Search (BFS). In this problem, we need to navigate through a grid where different symbols represent different cell types and find the minimum moves to reach the goal.

Grid Symbol Meanings

  • '#' is the goal cell that we want to reach
  • 'O' is a free cell via which we can travel to the goal cell
  • '*' is our current position in the grid
  • 'X' is a blocked cell, via which we cannot travel

Problem Example

Given the following grid ?

X X O X
X X * X
X # O X
X X X X

The shortest path from '*' to '#' requires 2 moves: down to 'O', then left to '#'.

Algorithm Steps

  • Find the starting position ('*') in the grid
  • Use BFS to explore all possible paths level by level
  • Mark visited cells to avoid revisiting
  • Return the number of moves when goal ('#') is reached
  • Return −1 if goal is unreachable

Implementation

def solve(grid):
    m, n = len(grid), len(grid[0])
    
    # Find starting position (*)
    for i in range(m):
        for j in range(n):
            if grid[i][j] == "*": 
                break
        else: 
            continue
        break
    
    # BFS initialization
    ans = 0
    queue = [(i, j)]
    grid[i][j] = "X"  # Mark as visited
    
    while queue:
        ans += 1
        newq = []
        
        # Process all cells at current level
        for i, j in queue:
            # Check all 4 directions (up, left, right, down)
            for ii, jj in [(i-1, j), (i, j-1), (i, j+1), (i+1, j)]:
                # Check bounds and if cell is accessible
                if 0 <= ii < m and 0 <= jj < n and grid[ii][jj] != "X":
                    if grid[ii][jj] == "#": 
                        return ans
                    newq.append((ii, jj))
                    grid[ii][jj] = "X"  # Mark as visited
        
        queue = newq
    
    return -1  # Goal not reachable

# Test with example grid
grid = [
    ['X', 'X', 'O', 'X'],
    ['X', 'X', '*', 'X'],
    ['X', '#', 'O', 'X'],
    ['X', 'X', 'X', 'X']
]

result = solve(grid)
print(f"Shortest path length: {result}")
Shortest path length: 2

How It Works

The algorithm uses Breadth-First Search to ensure we find the shortest path ?

  • Level-by-level exploration: BFS explores all cells at distance 1, then distance 2, and so on
  • Marking visited cells: We mark cells as 'X' to prevent revisiting and infinite loops
  • 4-directional movement: From each cell, we can move up, down, left, or right
  • Early termination: We return immediately when the goal '#' is found

Alternative Example

def solve_path(grid):
    m, n = len(grid), len(grid[0])
    
    # Find starting position
    start_i = start_j = None
    for i in range(m):
        for j in range(n):
            if grid[i][j] == "*":
                start_i, start_j = i, j
                break
        if start_i is not None:
            break
    
    if start_i is None:
        return -1  # No starting position found
    
    # BFS
    from collections import deque
    queue = deque([(start_i, start_j, 0)])  # (row, col, moves)
    visited = set()
    visited.add((start_i, start_j))
    
    directions = [(-1, 0), (1, 0), (0, -1), (0, 1)]  # up, down, left, right
    
    while queue:
        i, j, moves = queue.popleft()
        
        for di, dj in directions:
            ni, nj = i + di, j + dj
            
            if 0 <= ni < m and 0 <= nj < n and (ni, nj) not in visited:
                if grid[ni][nj] == "#":
                    return moves + 1
                elif grid[ni][nj] == "O":
                    visited.add((ni, nj))
                    queue.append((ni, nj, moves + 1))
    
    return -1

# Test unreachable case
unreachable_grid = [
    ['X', 'X', 'X', 'X'],
    ['X', '*', 'X', 'X'],
    ['X', 'X', 'X', '#'],
    ['X', 'X', 'X', 'X']
]

result = solve_path(unreachable_grid)
print(f"Unreachable case result: {result}")
Unreachable case result: -1

Conclusion

BFS guarantees finding the shortest path in unweighted grids by exploring cells level by level. The algorithm returns the minimum number of moves to reach the goal or −1 if unreachable.

Updated on: 2026-03-26T14:27:36+05:30

475 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements