day 18
boiling boulders
approach
the cubes go into a dict keyed by (x, y, z). part 1 counts, for every cube, the faces whose neighbour isn't a cube: six minus the number of occupied neighbours.
part 2 only wants faces reachable from outside, so it flood-fills the air. it takes a bounding box one unit larger than the droplet, seeds a breadth-first search with every cell on the six faces of that box, and spreads through empty cells. the result is the set of outside air cells; the answer counts, for each cube touched by the fill, the neighbours that are in that set.
the trick
flood-fill the air from outside a padded bounding box; trapped pockets are never reached, so their faces don't count.
python
res = 0
for c in boundary:
s = sum(1 for cn in neighbors(*c) if cn in seen)
res += s
return res