How to solve Advent of Code 2022 - Day 10 with Python
If you missed any previous days, click here for all my content about that: Advent of Code, if you want to know why you should participate and try to code the solution for yourself, click here: Advent Of Code 2022 – 7 Reasons why you should participate. If you're here to see the solution of Day 10, continue reading ;)
GitHub Repository
https://github.com/GalaxyInfernoCodes/Advent_Of_Code_2022
I will upload all of my solutions there - in the form of Python (or Scala alternatives) notebooks. You have to use your own input for the "input.txt" since everyone gets their own and everyone needs to provide a different solution based on their input.
Day 10 Puzzle
On day 10 of Advent of Code, we had to retrace the steps of a very simple CPU based on the commands it's given. There are two commands: addx and noop.
addx 13
addx 4
noop
addx -1
addx 5
As always, I read in all lines:
with open('input.txt', 'r') as f:
lines = f.readlines()
lines = [entry.strip() for entry in lines]
The CPU class
This following class models the CPU from the puzzle for both parts. The sum of registers is specifically needed for part 1, while the display is for part 2.
class SimpleCPU:
def __init__(self) -> None:
self.register_X = 1
self.cycle = 1
self.waiting_add = 0
self.wait = -1
self.sum_of_registers = 0
self.display = ""
def run_command(self, command):
if 'addx' in command:
add_nr = int(command.split(' ')[1])
self.wait = 2
self.waiting_add = add_nr
def advance_cycle(self):
if self.cycle in [20, 60, 100, 140, 180, 220]:
self.sum_of_registers += self.cycle * self.register_X
self.cycle += 1
self.wait -= 1
if self.wait == 0:
self.register_X += self.waiting_add
def print_cpu_state(self, part):
if part == 1:
if self.cycle in [20, 60, 100, 140, 180, 220]:
print(f"Completed cycles: {self.cycle}, register: {self.register_X}")
if self.wait > 0:
print(f"waiting add: {self.waiting_add} in {self.wait} cycles")
print('-----')
else:
sprite = [self.register_X - 1, self.register_X, self.register_X + 1]
if (self.cycle-1) % 40 in sprite:
self.display += "O"
else:
self.display += "_"
if len(self.display) == 40:
print(self.display)
self.display = ""
The main loop
After reading in the lines, we initiate a CPU and then run through the lines. It is important to check if the CPU is still busy with a 2-cycle add command, before taking the next command from our input.
def solve(file, part=1):
with open(file, 'r') as f:
lines = f.readlines()
lines = [entry.strip() for entry in lines]
cpu = SimpleCPU()
while len(lines) > 0 or cpu.wait > 0:
if cpu.wait > 0:
pass
else:
line = lines.pop(0)
cpu.run_command(line)
cpu.print_cpu_state(part=part)
cpu.advance_cycle()
if part == 1:
print('sum of signal strenghts', cpu.sum_of_registers)
Part 1
In part 1 we specifically need the sum of registers which is built up in the following code (excerpt from above):
def advance_cycle(self):
if self.cycle in [20, 60, 100, 140, 180, 220]:
self.sum_of_registers += self.cycle * self.register_X
solve('example2.txt', part=1)
Part 2
In part 2, we had to look ourselves at the printed output generated, by checking if the current position (which annoyingly ended up being cycle
-1 for me, because the position of the cursor starts at 0 while the cycle
starts counting at 1) is within one distance to the current register_X
value, and if so it prints a symbol.
sprite = [self.register_X - 1, self.register_X, self.register_X + 1]
if (self.cycle-1) % 40 in sprite:
self.display += "O"
else:
self.display += "_"
if len(self.display) == 40:
print(self.display)
self.display = ""
# example output, for the personal input, you can see capital letters in here
OO__OO__OO__OO__OO__OO__OO__OO__OO__OO__
OOO___OOO___OOO___OOO___OOO___OOO___OOO_
OOOO____OOOO____OOOO____OOOO____OOOO____
OOOOO_____OOOOO_____OOOOO_____OOOOO_____
OOOOOO______OOOOOO______OOOOOO______OOOO
OOOOOOO_______OOOOOOO_______OOOOOOO_____
Conclusion
Off by one errors are the worst. The CPU simulation was a nice touch, but debugging was frustrating especially the visual aspect since we did not have a real example of what the "hidden" capital letters would look like. I struggled to realize that I had an error in my code - the letter wasn't just wonky, it was indeed missing pixels...