Origial Animation in CodePen.io

Escape Pods

Created: Oct 27, 2026

Last modified: Oct 28, 2026

* AI-generated from the code I used in Google Foobar

TL, DR.

Escape Pods
===========

You've blown up the LAMBCHOP doomsday device and relieved the bunnies of their work duries -- and now you need to escape from the space station as quickly and as orderly as possible! The bunnies have all gathered in various locations throughout the station, and need to make their way towards the seemingly endless amount of escape pods positioned in other parts of the station. You need to get the numerous bunnies through the various rooms to the escape pods. Unfortunately, the corridors between the rooms can only fit so many bunnies at a time. What's more, many of the corridors were resized to accommodate the LAMBCHOP, so they vary in how many bunnies can move through them at a time.

Given the starting room numbers of the groups of bunnies, the room numbers of the escape pods, and how many bunnies can fit through at a time in each direction of every corridor in between, figure out how many bunnies can safely make it to the escape pods at a time at peak.

Write a function solution(entrances, exits, path) that takes an array of integers denoting where the groups of gathered bunnies are, an array of integers denoting where the escape pods are located, and an array of an array of integers of the corridors, returning the total number of bunnies that can get through at each time step as an int. The entrances and exits are disjoint and thus will never overlap. The path element path[A][B] = C describes that the corridor going from A to B can fit C bunnies at each time step.  There are at most 50 rooms connected by the corridors and at most 2000000 bunnies that will fit at a time.

For example, if you have:
entrances = [0, 1]
exits = [4, 5]
path = [
  [0, 0, 4, 6, 0, 0],  # Room 0: Bunnies
  [0, 0, 5, 2, 0, 0],  # Room 1: Bunnies
  [0, 0, 0, 0, 4, 4],  # Room 2: Intermediate room
  [0, 0, 0, 0, 6, 6],  # Room 3: Intermediate room
  [0, 0, 0, 0, 0, 0],  # Room 4: Escape pods
  [0, 0, 0, 0, 0, 0],  # Room 5: Escape pods
]

Then in each time step, the following might happen:
0 sends 4/4 bunnies to 2 and 6/6 bunnies to 3
1 sends 4/5 bunnies to 2 and 2/2 bunnies to 3
2 sends 4/4 bunnies to 4 and 4/4 bunnies to 5
3 sends 4/6 bunnies to 4 and 4/6 bunnies to 5

So, in total, 16 bunnies could make it to the escape pods at 4 and 5 at each time step.  (Note that in this example, room 3 could have sent any variation of 8 bunnies to 4 and 5, such as 2/6 and 6/6, but the final solution remains the same.)

Languages
=========

To provide a Java solution, edit Solution.java
To provide a Python solution, edit solution.py

Test cases
==========
Your code should pass the following test cases.
Note that it may also be run against hidden test cases not shown here.

-- Java cases --
Input:
Solution.solution({0, 1}, {4, 5}, {{0, 0, 4, 6, 0, 0}, {0, 0, 5, 2, 0, 0}, {0, 0, 0, 0, 4, 4}, {0, 0, 0, 0, 6, 6}, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0}})
Output:
    16

Input:
Solution.solution({0}, {3}, {{0, 7, 0, 0}, {0, 0, 6, 0}, {0, 0, 0, 8}, {9, 0, 0, 0}})
Output:
    6

-- Python cases --
Input:
solution.solution([0], [3], [[0, 7, 0, 0], [0, 0, 6, 0], [0, 0, 0, 8], [9, 0, 0, 0]])
Output:
    6

Input:
solution.solution([0, 1], [4, 5], [[0, 0, 4, 6, 0, 0], [0, 0, 5, 2, 0, 0], [0, 0, 0, 0, 4, 4], [0, 0, 0, 0, 6, 6], [0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0]])
Output:
    16

The LAMBCHOP is rubble and everyone needs to get out. The bunnies are huddled in a few rooms of the station, the escape pods sit in others, and the corridors in between come in all sizes: some fit 2 bunnies at a time, others fit 8. The question isn't how long it takes to get everybody out. It's how many bunnies can reach the pods per time step once the station is running at full speed.

Full disclosure up front: I didn't solve this one on my own. At level 4, the only one I cracked by myself was Bringing a Gun to a Trainer Fight; I got through this one with outside help. What follows explains how the solution I submitted works.

# Corridors are pipes

Draw the station as a graph. Rooms are nodes, and each corridor is an arrow from A to B with a capacity, which is exactly what path[A][B] holds. A 0 means there's no corridor. Traffic in both directions between two rooms means two separate arrows, each with its own number.

Every time step follows two rules. No corridor carries more bunnies than it fits. And nobody piles up in a room along the way: whoever walks in also walks out. That's how water behaves in a network of pipes, and the problem has a name: maximum flow. Bunnies per step are the flow, the bunnies' rooms are the sources and the pods are the sinks.

# Lots of sources, lots of sinks

Max-flow algorithms expect one source and one sink, and this problem can have several of each. The fix is to make up two extra rooms. A super source S gets an unlimited corridor to every room with bunnies, and a super sink T gets an unlimited corridor from every pod. Those new corridors never slow anyone down, so the max flow from S to T is exactly the answer. That's the job of transform in my code: it wraps the matrix with a new row and column on each side.

# Ford-Fulkerson: find a path with room to spare

Ford-Fulkerson is about as intuitive as it gets. Find a path from S to T where every corridor still has room for at least one more bunny. Send as many bunnies down it as its narrowest corridor allows (the bottleneck), write that down, and look for another path. Stop when there are none left.

Each path comes from a BFS, the same one from Prepare the Bunnies' Escape, except that a corridor counts as open while it has room left. Since BFS always finds the shortest path first, this flavor has its own name: Edmonds-Karp. That buys a nice guarantee: it always finishes, in $O(V \cdot E^2)$ time no matter how big the capacities are. With 50 rooms, that's nothing.

# The trick: sending bunnies back

On its own, that greedy loop can get stuck. Take the third example in the demo. Every corridor fits 1 bunny, and the first path found is 0 → 1 → 3 → 5. That fills 3 → 5, and room 2 only leads to room 3. Nothing else seems to fit, so you'd answer 1. The real answer is 2: the bunny going through room 1 should have taken 4 instead, leaving room 3 free for the one coming from 2.

Ford-Fulkerson handles this without any guesswork. Whenever bunnies go from u to v, it also opens the option of "sending them back" from v to u. That's the reverse edge, and in the code it's these two lines:

$$ \text{flows}[u][v] \mathrel{+}= \delta \qquad \text{flows}[v][u] \mathrel{-}= \delta $$

Subtracting from flows[v][u] makes the room left on the way back, path[v][u] - flows[v][u], go up, even if that corridor doesn't exist at all. So the second BFS can go 0 → 2 → 3, step back from 3 to 1 to cancel the earlier shipment, and carry on through 1 → 4 → 5. Nobody actually walks backwards. In the end, one bunny takes 0 → 1 → 4 → 5 and the other takes 0 → 2 → 3 → 5.

# Watch the corridors fill up

Pick an example and step through it with the slider or the play button. Each step is one turn of the while True loop: the BFS path turns green, bunnies run along it, and every corridor shows flow/capacity, with thicker arrows for fuller corridors. In the third example, watch for the dashed arrow on the second path: those are the bunnies being sent back. Turn on "Show S and T" to see the super source and super sink too.

Example
0/70/60/80/9 0🐰 1 2 3🚀

An empty station: nobody's moving yet. The BFS is about to find 1 path.

Legend: Corridor with bunnies, flow/capacity (thicker the fuller it is) Path the BFS found on this turn Bunnies sent back through a corridor (reverse edge) Full corridors of the minimum cut Rooms the last BFS still reaches

# How do we know it's the best?

The demo's last step answers that. When the BFS can no longer reach T, the rooms it did reach (the shaded ones) are cut off from the rest by corridors that are completely full. That set of corridors is called a cut, and every bunny that makes it to a pod has to cross it. So no flow can ever be larger than the sum of its capacities.

In the second example, the final BFS reaches rooms 0, 1 and 2, and the cut is made of 0 → 3, 1 → 3, 2 → 4 and 2 → 5: 6 + 2 + 4 + 4 = 16, the same as the flow we found. If the flow already fills a wall that everyone has to get through, there's no room for a single extra bunny. That's the max-flow min-cut theorem, and it's why Ford-Fulkerson can stop with a clear conscience once it runs out of paths.

# The code

Here's the code I submitted, written for Python 2.7, which is what Foobar ran:

inf is Decimal("Infinity"), the "no limit" for the corridors out of S and into T. Any number above 2,000,000 would do, since that's the most bunnies per step the statement allows.

transform shifts every room one index up, puts S at 0 and T at the end, and links the entrances and the pods with inf. It edits the matrix it's given instead of building a new one.

bfs only crosses corridors with room left, path[u][v] - flows[u][v] > 0, and stores in parents where it came from for each room. If it reaches the end, it walks the path backwards to find the bottleneck.

solution keeps running the BFS while it finds paths. For each corridor on the path, it adds the bottleneck and subtracts it from the reverse edge.

import decimal


# Ford-Fulkerson Algorithm
inf = decimal.Decimal("Infinity")


def bfs(start, end, path, flows):
    global inf
    length = len(path)
    parents = [-1] * length  # parent table for reverse tracing path
    parents[start] = -2  # differentiate start point from others
    queue = []
    queue.append(start)
    while queue and parents[end] == -1:
        u = queue.pop(0)
        for v in range(length):
            cf = path[u][v] - flows[u][v]
            if cf > 0 and parents[v] == -1:
                queue.append(v)
                parents[v] = u
    if parents[end] == -1:  # if t can not been reached
        return 0, parents
    v = end
    delta = inf
    while v != start:
        u = parents[v]
        cf = path[u][v] - flows[u][v]
        delta = min(delta, cf)
        v = u
    return delta, parents


def transform(entrances, exits, path):
    global inf
    length = len(path)
    entrances = [i + 1 for i in entrances]
    exits = [i + 1 for i in exits]
    for row in path:
        row.insert(0, 0)
        row.append(0)
    start_row = [0] * (length + 2)
    for i in entrances:
        start_row[i] = inf
    path.insert(0, start_row)
    end_row = [0] * (length + 2)
    for i in exits:
        path[i][-1] = inf
    path.append(end_row)
    return entrances, exits, path


def solution(entrances, exits, path):
    transform(entrances, exits, path)
    flow = 0
    length = len(path)
    flows = [[0 for i in range(length)] for j in range(length)]
    start = 0
    end = length - 1
    while True:
        ap_flow, parents = bfs(start, end, path, flows)
        if ap_flow == 0:
            break
        flow += ap_flow
        v = end
        while v != start:
            u = parents[v]
            flows[u][v] += ap_flow
            flows[v][u] -= ap_flow
            v = u
    return flow
# Wrapping up

The statement talks about bunnies, corridors and time steps, but underneath it's plain maximum flow. Once you see that, two ideas do the rest: merge every source and every sink into a single one, and let later paths fix earlier ones through reverse edges. Whenever a problem asks "how much fits at once" through a network with limits, it's worth asking whether it's a flow in disguise.

An unhandled error has occurred. Reload 🗙