Advent of Code 2023 - Day 20Pulse Propagation
| Problem statement | Source code | Tags: BFS/DFSPuzzleManual inspectionPeriod finding
Part 1
I'm using igraph to represent the circuit graph. Each node contains:
type:%,&,broadcaster, or nothing (pure output)labelstate: for%, a boolean that'sFALSEforoffandTRUEforon. For&, a bitset of the remembered inputs; starting as0for all inputs low.
Now I need to implement pushing the button. I basically use a BFS approach, keeping a queue of pulses. Each pulse is the source and target nodes and its level. Each time I pop a pulse, I deliver it to the target node and update its state and generate new pulses as needed. I keep track of the number of low and high pulses generated.
Flip-flops flip their state on low pulse:
Conjunctions update their memory and output low only if all memory is high (i.e., 1 << n - 1):
Part 2
Another period finding problem, like day 8. However, unlike day 8, it's not immediately clear how the cycle can be decomposed into several independent subcycles, and just simulating the whole thing turned out to never finish. However, plotting the graph reveals important structural information:

The graph starts at the broadcaster, going to four different clusters of flip-flops. Each cluster is eventually connected to a single conjunction (zp, nx, dj, bz), which then go into four other conjunctions (bh, vd, ns, dl), which then go into a final conjunction (zh) before sending to rx. Therefore, if rx receives a single low pulse, that means zh received a high pulse from every input. Therefore, I just need to repeatedly push buttons and check when each input to zh sent a high pulse.
My push_btn now takes an optional track_inputs that takes a node to track for its input pulses. Each time I send a pulse to track_inputs, I record the source node and the level of the pulse.
Then I record the cycle length for each input to zh.
Finally I just need to find the LCM of these cycle lengths.
Is this completely safe? Probably not. If I see a single high pulse from an input to zh to , that does not guarantee that a high pulse comes in every , which requires the subcircuit to be completely reset to the default state at time . This probably has something to do with the structure of each subcircuit—probably it's a modular counter, and a high input is sent when all flip-flops are on? I didn't investigate this further, because the approach above already works.