Lowest Toll

Lowest Toll

Each cell of a grid charges a toll (a non-negative integer) to enter it. Starting on the top-left cell and moving up/down/left/right, return the minimum total toll to reach the bottom-right cell. The toll of every cell you stand on counts, including the start and the end.

lowestToll(grid)

Input format: rows separated by ;, values space-separated.

Examples

[[1,3],[2,1]]           // → 4    (1 → 2 → 1)
[[1,2,3],[4,5,6]]       // → 12   (1→2→3→6) or (1→4→5→6)... min is 1+2+3+6=12
[[5]]                   // → 5

Walkthrough

Reframing the grid as a graph

Strip the grid dressing: every cell is a node, moving between adjacent cells is an edge costing the entered cell's toll. You want the cheapest total to get from top-left to bottom-right. Since tolls vary, fewest-moves (BFS) isn't enough — you need cheapest accumulated cost, which is Dijkstra's territory.

Why you can't just try every path

With four-directional movement, the grid has exponentially many corner-to-corner paths — brute force is out. The standard shortest-path insight: track the best toll found so far for every cell, and greedily commit to the cheapest unresolved cell each step, since non-negative tolls mean no future discovery through a currently-pricier cell could beat the one you're about to commit to.

Building the approach

  1. Seed the top-left cell's cost with its own toll; every other cell starts at infinity.
  2. Repeatedly pick and finalize the unfinalized cell with the smallest known cost — provably optimal by the same non-negative argument.
  3. From that cell, check its unfinalized neighbors. For each, compute the cost via this cell (finalized cost plus the neighbor's toll), and update if cheaper.
  4. Repeat until the bottom-right cell is finalized. Its cost is the answer.

Why this differs from a naive "always move toward the corner" approach

Always stepping right or down seems natural, but a locally cheap cell can lead into an expensive patch, while a detour — even backward or sideways — might route around a costly region for less total cost. A wall of high-toll cells makes this concrete: the cheapest route might dodge an expensive column entirely by going down first, which a strict right/down-only walk would miss. Dijkstra doesn't commit to a direction — it always expands from whichever reachable cell currently has the lowest total cost, guaranteeing the true minimum.

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