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