# [Advent Of Code 2022] Day 10: Cathode-Ray Tube [SPOILERS]

Solved this in a fairly straightforward way. Always fun to write things to the console as part of a solution.

Ruby Solution
``````registers = File.readlines('inputs/10.txt', chomp: true).inject([1]) do |history, instruction|
case instruction.split(' ')
in ['noop'] then history.push(history.last)
in ['addx', value] then history.push(history.last).push(history.last + value.to_i)
end
end

a = [20, 60, 100, 140, 180, 220].sum {|cycle| cycle * registers[cycle - 1] }
b = registers[0..-2].each_slice(40).map do|row|
row.each_with_index.map {|register, col| (register - col).abs <= 1 ? "#" : '.' }.join + "\n"
end.join

require 'minitest/autorun'

expected_b = <<~B
####.####.###..####.#..#..##..#..#.###..
...#.#....#..#.#....#..#.#..#.#..#.#..#.
..#..###..###..###..####.#....#..#.#..#.
.#...#....#..#.#....#..#.#.##.#..#.###..
#....#....#..#.#....#..#.#..#.#..#.#....
####.#....###..#....#..#..###..##..#....
B

describe 'day 10' do
it 'part a' do assert_equal 15_680, a end
it 'part b' do assert_equal expected_b, b end
end
``````

Flashbacks to 2019. I hope we won’t do something like Intcode this year.

Python Solution
``````def read_file(file: TextIO) -> tuple[str, tuple[int, ...]]:
lines = (line.split() for line in file)
return [(cmd, tuple(int(arg) for arg in args)) for cmd, *args in lines]

def run_program(program: tuple[str, tuple[int, ...]]) -> list[int]:
"""Determine the value of the register 'X' for each cycle."""
result = []
reg_x = 1
for cmd, args in program:
if cmd == 'noop':
result.append(reg_x)
result.append(reg_x)
result.append(reg_x)
reg_x += args[0]
return result

def part1(file: TextIO) -> int:
"""Solve the first part of the puzzle."""
reg_x_values = run_program(program)
signal_strengths = (reg_x * i for i, reg_x in enumerate(reg_x_values, 1))
return sum(itertools.islice(signal_strengths, 19, None, 40))

def part2(file: TextIO) -> str:
"""Solve the second part of the puzzle."""
crt = [['.'] * 40 for _ in range(6)]
signals = run_program(program)
for i, reg_x in enumerate(signals):
# pylint: disable-next=invalid-name
y, x = divmod(i % (6 * 40), 40)
if reg_x - 1 <= x <= reg_x + 1:
crt[y][x] = '#'
else:
crt[y][x] = '.'
return '\n'.join(''.join(line) for line in crt)
``````

I got tripped up multiple times trying to solve this, by performing the operations in the wrong order (updating the register too early in the cycle).

I finally added an “OCR” to my library. It converts the pixels (`list[list[bool]]`) to a series of bits which is then just an `int`. Combine that with a `map[int, char]` and I can run this type of exercise through the “OCR” logic and get a string!

Code: FinalJust Make It Work

Python Solution
``````    def run_program(self, lines: InputType) -> list[int]:
regx = 1
regx_values = []
size = {"addx": 2, "noop": 1}
for parts in lines:
for _ in range(size[str(parts[0])]):
regx_values.append(regx)
regx += int(parts[1])
return regx_values

def part1(self, parsed_input: InputType) -> int:
regx_values = self.run_program(parsed_input)
out = 0
for cycle in range(20, 240, 40):
out += regx_values[cycle - 1] * cycle
return out

def part2(self, parsed_input: InputType) -> str:
regx_values = self.run_program(parsed_input)

pixels = []
for cycle, regx in enumerate(regx_values):
horizontal_position = cycle % 40
pixels.append(abs(horizontal_position - regx) <= 1)

rows = [pixels[i*40:(i+1)*40] for i in range(6)]
return aoc.OCR(rows).as_string()
``````