Skip to content
advent of code 2022

day 17

pyroclastic flow

approach

the chamber is a dict of blocked cells and a highest row. each Rock is drawn from a small ascii picture, and Grid.add spawns it above the stack, alternates a jet push from a GasStream (which wraps around its pattern) with a fall of one row, and stops when it can't fall. it returns where the rock landed relative to the top, plus the jet index.

part 1 drops 2022 rocks and reads the height. part 2 needs a trillion, so it looks for a cycle: it drops rocks in batches, keys each batch by the tuple of (jet index, relative row, column) for every rock in it, and stops when a key repeats. the height gained per cycle is multiplied out, and the leftover rocks are simulated normally on top.

the trick

once a batch of rocks lands the same way relative to the top, with the jets in the same place, the tower repeats; skip ahead by whole cycles.

python
    while (t := tuple(grid.add_bulk(rocks, gas))) not in seen:
        i += len(rocks)
        seen[t] = (i, grid.highest, gas.i)
    i += len(rocks)
    ph = grid.highest
    diff_height = ph - seen[t][1]
    diff_i = i  - seen[t][0]
    limit -= seen[t][0]
    h = seen[t][1]
    d, m = divmod(limit, diff_i)
    h += d * diff_height