The elves fixed the sand machines, but they need to be booted up.
The machines are connected with cables, and each machine has a communication module attached to it.
Those modules communicate using pulses, either a high pulse, of a low pulse.
A module sends its pulse to all of its destination modules.
Today’s input describes to grid of modules.
An example input looks like this:
Each line describes a module:
To the left of the arrow is the source module.
To the right of the arrow are its destination modules
A module can have several types:
A flipflop module, its name is prefixed with a %
A conjugation module, its name is prefixed with a &
The broadcaster module, each grid has one of these
Module behaviour
Flip-flop modules (prefix %) are either on or off.
They are initially off.
If a flip-flop module receives a high pulse, it is ignored and nothing happens.
However, if a flip-flop module receives a low pulse, it flips between on and off.
If it was off, it turns on and sends a high pulse. If it was on, it turns off and sends a low pulse.
Conjunction modules (prefix &) remember the type of the most recent pulse received from each of their connected input modules.
They initially default to remembering a low pulse for each input.
When a pulse is received, the conjunction module first updates its memory for that input.
Then, if it remembers high pulses for all inputs, it sends a low pulse; otherwise, it sends a high pulse.
There is a single broadcast module (named broadcaster).
When it receives a pulse, it sends the same pulse to all of its destination modules.
The button module.
When you push the button, a single low pulse is sent directly to the broadcaster module.
Pulses are processed in the order they are sent.
In other words, every time a pulse is sent, push onto the back of queue.
The next pulse to be processed is the next pulse you pop off the front of the queue.
Parsing
I parsed the input into 2 maps.
From a name to a list of destinations
From a name to a module
A module:
A flipflop module has an internal boolean to determine if it’s on.
The memory of a conjugation module keeps track of the previous strength each of its input modules sent previously.
Part 1
Press the button 1000 times.
The question asks what you get if you multiply the total number of low pulses sent by the total number of high pulses sent?
Helpers
The queue holds a Pulses:
A method on Pulse that allows it to be sent.
It figures out which pulse strength it would send (if any), and then sends that pulse to all of its destinations (by pushing a new Pulse onto the queue).
Code
Part 2
The final module is named "rx".
The machine turns on when a single low pulse is sent to "rx".
The question asks what the fewest number of button presses required to deliver a single low pulse to the module named rx is.
This part required some investigation of the input file.
The singular module before "rx" is always a conjugation module.
So if all modules connected to that module have previously sent a high strength signal, it will send a low strength signal.
That’s the condition to look for, after how many button presses does that happen?
I kept track of how many button presses it takes for each module connected to that final conjugation module to send a high signal.
If I’ve seen all those modules sent a high signal, I determine when they would have all sent one previously.
Like previous days, this is the least common multiple of all individual button presses.
Helpers
A way to calculate the least common multiple of 2 numbers: