day 13
packet scanners
approach
the scanners are never simulated. a scanner with range r is back at the top every 2r - 2 picoseconds, so a packet entering layer d after a delay is caught exactly when (d + delay) % (2r - 2) == 0.
part 1 sums depth * range over the layers that catch the packet with no delay. part 2 tries delays from 0 upward until no layer catches it. the rust version does the same thing, returning None from severity when the packet slips through.
the trick
a scanner's position is periodic with period 2r - 2, so being caught is a single modulo check.
python
def severity(d, delay):
l = [k * v for k, v in d.items() if ((k+delay) % (v + v - 2)) == 0]
return l