Advent of Code 2019 - Day 7
Advent of Code 2019 - Day 7
Intro
Day 7 brings another Intcode puzzle, so I finally bit the bullet and refactored my vm. I’m writing this after reading the prompt for day 9, so I’m getting the sense more refactoring might be coming soon. For now, let’s cover day 7’s solution.
As always, you can find my full solutions repo here.
Solution
The main thing I’ve done to refactor my Intcode vm is to encapsulate it inside
a class. The instance will now keep track of the program counter and the
internal memory/program. The primary interface to the class is the
compute(inputs)
method, which takes a list of inputs and returns an output
value and an associated code (“halt” or “output”). This problem requires you to
use previous outputs as inputs to the next amp, so I had to modify the compute
method accordingly.
With the new Intcode computer, the rest of the part one falls into place easily. Generate all permuations of amp settings and then iterate through them, using the vm to compute the max thrust.
phase_settings = list(permutations([0, 1, 2, 3, 4], 5))
max_thrust = -1
program = prep_intcode_program("./input/day7.txt")
for amp_config in phase_settings:
line_in = 0
for amp in amp_config:
computer = IntcodeComputer(program.copy())
line_in, halt_type = computer.compute([amp, line_in])
line_in = line_in
if line_in > max_thrust:
max_thrust = line_in
The second part throws a wrench into the puzzle by requiring you to pass one amp’s output into the next amp’s input. This is the spec change that made me have to do a refactor that allowed for output but retained the instance’s program counter.
I’m using the same general approach of iterating through possibile amp configurations and comparing the final 5th amp output to the max seen thusfar. This is pretty messy, but I’m getting shit done over here.
for amp_config in phase_settings:
first_run = True
found = False
amps = [IntcodeComputer(program.copy()) for i in range(0, 5)]
amp_id = 0
last_e_signal = -1
line_in = 0
while not found or amp_id != 0:
if first_run:
line_in = [amp_config[amp_id], line_in]
else:
line_in = [line_in]
line_in, halt_type = amps[amp_id].compute(line_in)
if halt_type == "output" and amp_id == 4:
last_e_signal = line_in
if halt_type == "halt":
found = True
if amp_id == 4:
first_run = False
amp_id = (amp_id + 1) % 5
if last_e_signal > max_thrust:
max_thrust = last_e_signal
Hopefully this version of the Intcode vm will be more extensible for future Intcode puzzles.
As always, you can find my full solutions repo here.