day 11
seating system
approach
the seat layout is a grid of characters. step scans every seat, counts occupied neighbours, and collects the changes in a dictionary before applying them, so every seat updates from the same snapshot. an empty seat with no occupied neighbours fills; an occupied one empties once the count reaches a tolerance. it returns the number of changes, and the parts loop until that is zero, then count #.
the two parts share step and differ only in the neighbour function passed in and the tolerance. part 1 uses the eight adjacent cells and a tolerance of 4. part 2 uses visible, which looks along each of the eight directions past floor cells to the first seat, with a tolerance of 5.
the trick
pass the neighbour rule in as a function, so both parts run the same simulation.
def visible_dir(m, r, c, dr, dc):
rws, cls = len(m), len(m[0])
cr, cc = r + dr, c + dc
while 0 <= cr < rws and 0 <= cc < cls and m[cr][cc] == '.':
cr += dr
cc += dc
if 0 <= cr < rws and 0 <= cc < cls and m[cr][cc] != '.':
return m[cr][cc]
return None