Sean McLemon | Advent of Code

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


2016-12-12 - Leonardo's Monorail

(original .ipynb)
from collections import defaultdict

puzzle_input_str = open("puzzle_input/day12.txt").read()

test_input_str = """cpy 41 a
inc a
inc a
dec a
jnz a 2
dec a"""


def value(regs, n):
    if n.isalpha():
        return regs[n]
    return int(n)
    

# cpy x y copies x (either an integer or the value of a register) into register y.
def cpy(regs, x, y):
    regs[y] = value(regs, x)
    return 1


# inc x increases the value of register x by one.
def inc(regs, x):
    regs[x] += 1
    return 1


# dec x decreases the value of register x by one.
def dec(regs, x):
    regs[x] += -1
    return 1


# jnz x y jumps to an instruction y away (positive means forward; negative means backward), but only if x is not zero.
def jnz(regs, x, y):
    if value(regs, x) == 0:
        return 1    
    return int(y)


def parse(input_str):
    lines = input_str.split("\n")
    instructions = []
    for line in lines:
        line_parts = line.split(" ")
        instructions.append((line_parts[0], line_parts[1:]))
    return instructions


instr_lookup = {
    "cpy": cpy,
    "inc": inc,
    "dec": dec,
    "jnz": jnz
}


def run(instructions, regs):
    pc = 0
    while pc < len(instructions):
        instr, args = instructions[pc]
        pc += instr_lookup[instr](regs, *args)        

        
def part_one(input_str):
    instructions = parse(input_str)
    regs = defaultdict(lambda: 0)
    run(instructions, regs)
    return regs["a"]


assert 42 == part_one(test_input_str)

print("part one:", part_one(puzzle_input_str))
part one: 318077
def part_two(input_str):
    instructions = parse(input_str)
    regs = defaultdict(lambda: 0)
    regs["c"] = 1
    
    run(instructions, regs)
    return regs["a"]


assert 42 == part_one(test_input_str)

print("part two:", part_two(puzzle_input_str))
part two: 9227731