Dazbo's Advent of Code solutions, written in Python
It’s the final Assembunny challenge! This time, we need to find the right input for a program to generate a specific clock signal. The program uses the same Assembunny instruction set we’ve seen before, but with one addition: out x
, which transmits the value of x
as the next value for the clock signal.
Our goal is to find the lowest positive integer that, when used to initialize register a
, causes the program to output an endless, alternating pattern of 0, 1, 0, 1, ...
.
What is the lowest positive integer that can be used to initialize register a
?
My approach is to once again extend the Computer
class from Day 12. I’ll create a new class, Assembunny3
, that adds the _op_out
method.
The _op_out
method will append the output value to a string that represents the clock signal. After each output, it will check if the signal is valid. If it finds a repeating digit (e.g., 0, 0
or 1, 1
), it will raise a StopIteration
exception to terminate the program. If the signal gets long enough without any issues, we can be reasonably confident that we’ve found the correct input.
class Assembunny3(Computer):
def __init__(self) -> None:
self._clock_signal = ""
super().__init__()
@property
def clock_signal(self) -> str:
return self._clock_signal
def _op_out(self, instr_params:list):
self._clock_signal += str(self.int_or_reg_val(instr_params[0]))
if (len(self.clock_signal) >= 2 and
self.clock_signal[-1] == self.clock_signal[-2]):
raise StopIteration("Bad clock")
elif len(self.clock_signal) > 100:
raise StopIteration("Good clock!")
The main part of the program will then loop through positive integers, starting from 0, and use each one as the initial value for register a
. It will run the Assembunny program and catch the StopIteration
exception. If it’s a “Bad clock”, it will move on to the next integer. If it’s a “Good clock!”, it will print the integer and terminate.
def main():
# ... (load instructions)
reg_input = 0
while True:
computer = Assembunny3()
computer.set_register('a', reg_input)
try:
computer.run_program(data)
except StopIteration as err:
if err.value == "Bad clock":
# try next input value
else:
logger.info("Good clock with %d: %s", reg_input, computer.clock_signal)
break
reg_input += 1
There is no Part 2 for this puzzle! Merry Christmas!
Good clock with 189: 01010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010
Execution time: 2.1011 seconds
And that’s a wrap for Advent of Code 2016! It’s been a fun ride, with plenty of interesting challenges. The Assembunny problems, in particular, were a great way to explore interpreters and program optimization.