Sean McLemon | Advent of Code

Home | Czech | Blog | GitHub | Advent Of Code | Notes


2022-12-10 - Cathode-Ray Tube

(original .ipynb)

Day 10 puzzle input is a sequence of assembly-like instructions - addx {arg} which takes 2 cycles and noop which takes a single cycle - which operate on a single register x (mine is here). Part 1 involves making a cycle-accurate simulator that executes thsi code, and sampling the x register at given points in time (cycles 20, 60, 100, 140, 180 and 220) and calculating the sum of the x * elapsed_cycles at that point. Part 2 involves interpreting this in a fun and weird way such that it draws pixels on a simple 40x6 pixel display.

puzzle_input_str = open("./puzzle_input/day10.txt").read()
test_input_str = open("./test_input/day10.txt").read()

def parse_line(line):
    instr_parts = line.split(" ")
    if instr_parts[0] == "addx":
        yield 0
        yield int(instr_parts[1])
    else:
        yield 0


def parse_input(input_str):
    parsed_lines = [parse_line(line) for line in input_str.splitlines()]
    for parsed_line in parsed_lines:
        yield from parsed_line
    
        
def part_one(input_str):
    ys = parse_input(input_str)
    x = 1
    cycles = 1
    sample_cycles = {20,60,100,140,180,220}
    samples = 0
    
    for y in ys:
        if cycles in sample_cycles:
            samples += cycles * x
        x += y
        cycles += 1
    
    return samples


assert 13140 == part_one(test_input_str)

print("part one:", part_one(puzzle_input_str))
part one: 13220
def pixel_output(cycles, x):
    if x-1 <= cycles and cycles <= x+1:
        return "#" 
    return "."


def part_two(input_str):
    ys = parse_input(input_str)
    x = 1
    cycles = 1
    output = [pixel_output(cycles, x)]
    
    for y in ys:
        x += y
        output.append(pixel_output(cycles % 40, x))
        cycles += 1
        if cycles % 40 == 0:
            output.append("\n")
        
    return "".join(output[:-2]) # i'm off-by-one somewhere, I add an extra "." on a newline somehow?


expected_test_output = """##..##..##..##..##..##..##..##..##..##..
###...###...###...###...###...###...###.
####....####....####....####....####....
#####.....#####.....#####.....#####.....
######......######......######......####
#######.......#######.......#######....."""

assert expected_test_output == part_two(test_input_str)

print("part two:", "\n" + part_two(puzzle_input_str))
part two: 
###..#..#..##..#..#.#..#.###..####.#..#.
#..#.#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#.#..#.#..#.##...####.###..###..##...
###..#..#.####.#.#..#..#.#..#.#....#.#..
#.#..#..#.#..#.#.#..#..#.#..#.#....#.#..
#..#..##..#..#.#..#.#..#.###..####.#..#.