Closest Carrot

Closest Carrot

A grid has open cells (O), walls (X), and carrots (C). Starting from (startRow, startCol), return the length of the shortest path (number of steps, moving up/down/left/right through non-wall cells) to the nearest carrot. If no carrot is reachable, return -1.

closestCarrot(grid, startRow, startCol)

Input format: grid | startRow startCol, grid rows separated by |.

Examples

(OOO|OXO|OOC) from (0,0)   // → 4
(OO|OO) from (0,0)         // → -1   (no carrots)
(C) from (0,0)             // → 0

Walkthrough

Recognizing the shape of the problem

Strip away the grid dressing and this is the same shortest-path question: fewest steps from a start to some target, where every step costs the same. Whenever every move costs the same, BFS is the right tool — it explores outward in rings of increasing distance, guaranteeing the first time you reach any target, it's via the shortest route.

What's different from single-target shortest path

Earlier you searched for one specific destination. Here, any carrot cell counts, and you want the closest. This needs almost no change to BFS: since it visits cells in strict order of increasing distance, the very first carrot cell it dequeues is guaranteed closest — everything closer has already been checked and found not to be a carrot.

Modeling the grid as a graph, with walls

Each cell is a node connected to its up/down/left/right neighbours, but walls can't be moved into at all — they should never be enqueued, as if they and their edges don't exist.

Building the search

  1. Enqueue the starting cell at distance 0, and mark it visited immediately.
  2. Dequeue the earliest-added cell. If it holds a carrot, its distance is the answer.
  3. Otherwise, for each neighbour that's in bounds, not a wall, and not visited, mark it visited and enqueue at distance + 1.
  4. If the queue empties without a carrot, return -1.

Why marking visited at enqueue time still matters

Just as with general shortest path, marking a cell visited the moment it's enqueued (not when processed) prevents it being queued multiple times via different routes, which would waste work and risk the wrong recorded distance. This is what keeps the ring-by-ring guarantee intact.

main.py
Console
Press Run to execute your code, or Submit to test and complete this problem.