Logo for ammarahmed.ca
Medium
Jan 14, 2026
#graph
#bfs

Infinite Taxi Driver

In an alternate world, we encounter a remarkable city characterized by a perfect grid system. The city's roads run exclusively north-south and east-west, forming a grid where each block is a 1-mile by 1-mile square, with parallel roads spaced 1 mile apart. This grid extends infinitely in all directions. Each intersection on this grid can be represented as a coordinate point (x, y) (x, y). As a taxi driver, you start at a specific location with the goal of reaching your destination. However, you are restricted to driving only along the city's roads, meaning you can move solely in the cardinal directions: north, south, east, and west.

1 2Legend: 3 C: Cab 4 D: Destination 5 Initial Grid: 6 Infinitely More Expansions 7 . . . . . . . . . . . 8 Y . . . . . . . . . . . 9 ... 6 _ _ _ _ _ _ _ _ _ _ _ ... 10 ... 5 _ _ _ _ _ _ _ _ _ _ _ ... 11 ... 4 _ _ _ _ _ _ _ _ _ _ _ ... 12 ... 3 _ _ _ _ _ _ _ _ D _ _ ... 13 ... 2 _ _ _ _ _ _ _ _ _ _ _ ... 14 ... 1 _ _ _ _ _ _ _ _ _ _ _ ... 15 ... 0 _ _ _ C _ _ _ _ _ _ _ ... 16 0 1 2 3 4 5 6 7 8 9 10 X 17 . . . . . . . . . . . 18 . . . . . . . . . . . 19 Infinitely More Expansions

We now introduce the concept of barriers. Barriers are placed at specific intersections, preventing the taxi driver from passing through them.

Given the presence of these barriers, there are two objectives:

Determine the shortest possible route the driver can take to reach their destination. Determine the minimum time required for the driver to reach the destination, assuming each step the taxi takes is equivalent to 1 second.

1 2Legend: 3 C: Cab 4 D: Destination 5 X: Barrier 6 7Grid with Barriers: 8 9 Infinitely More Expansions 10 . . . . . . . . . . . 11 Y . . . . . . . . . . . 12... 6 _ _ _ _ _ _ _ _ _ _ _ ... 13... 5 _ _ _ _ _ _ _ _ _ _ _ ... 14... 4 _ _ _ _ _ _ _ X _ _ _ ... 15... 3 _ _ _ _ _ _ _ X D _ _ ... 16... 2 _ _ _ _ _ _ _ X X _ _ ... 17... 1 _ _ _ _ _ _ _ X _ _ _ ... 18... 0 _ _ _ C _ _ _ X _ _ _ ... 19 0 1 2 3 4 5 6 7 8 9 10 X 20 . . . . . . . . . . . 21 . . . . . . . . . . . 22 23 Infinitely More Expansions

Example 1:

1Input: 2 Cab: (3,0) 3 Destination: (8,3) 4 Barriers: (7,0), (7,1), (7, 2), (7,3), (7,4), (8,2) 5Output: 6 any path of length 12 is a valid solution. 7 path = "NNNNNEEEEESS" 8 path = "SEEEEEENNNNW"

[execution time limit] 3 seconds (java) [memory limit] 2g

Notes

Intuition

On an infinite grid with barriers, BFS finds the shortest path. Each cell has 4 neighbors (N, S, E, W), and we track the path as a string of directions.

Implementation

Generate neighbors as (direction, coordinate) pairs. No bounds checking needed on an infinite grid. BFS from start with queue entries of (coordinate, path_string). Track visited coordinates. For each neighbor, skip if visited or a barrier. If it's the destination, return the accumulated path. Otherwise, add to queue with the extended path.

Edge-cases

If start equals destination, return empty string. The algorithm guarantees the shortest path due to BFS properties. Could be optimized with A* using Manhattan distance heuristic.

  • Time: O(V) — where V is the number of reachable states
    • Space: O(V) — visited set and queue

      Complexity

      Solution

      1from typing import List, Tuple 2from collections import deque 3 4class Solution: 5 def neighbours(self, coord: Tuple[int, int]) -> List[Tuple[str, Tuple[int, int]]]: 6 dirs = [("N", (0, 1)), ("S", (0, -1)), ("W", (-1, 0)), ("E", (1, 0))] 7 result = [] 8 x, y = coord 9 for cardinal, dir in dirs: 10 dx, dy = dir 11 nx, ny = x + dx, y + dy 12 result.append((cardinal, (nx, ny))) 13 return result 14 15 def manhattan(self, a: Tuple[int, int], b: Tuple[int, int]) -> int: 16 return abs(a[0] - b[0]) + abs(a[1] - b[1]) 17 18 def findPath(self, cab: Tuple[int, int], destination: Tuple[int, int], barriers: List[Tuple[int,int]]) -> str: 19 if cab == destination: 20 return "" 21 22 q = deque([(cab, "")]) 23 visited = set([cab]) 24 blocked = set(barriers) 25 while q: 26 curr, path = q.popleft() 27 for n_dir, n_coord in self.neighbours(curr): 28 if n_coord in visited or n_coord in blocked: 29 continue 30 if n_coord == destination: 31 return path + n_dir 32 33 q.append((n_coord, path + n_dir)) 34 visited.add(n_coord) 35 return "" 36 37if __name__ == "__main__": 38 # Include one-off tests here or debugging logic that can be run by running this file 39 # e.g. print(solution.two_sum([1, 2, 3, 4], 3)) 40 solution = Solution() 41