Sean McLemon | Advent of Code

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


2017-12-08 - I Heard You Like Registers

(original .ipynb)
import math
from collections import defaultdict

puzzle_input_test = """
b inc 5 if a > 1
a inc 1 if b < 5
c dec -10 if a >= 1
c inc -20 if c == 10
"""

puzzle_input = open("./puzzle_input/day8.txt", "r").read()

def cmp_gt(register_file, reg, val):
    return register_file[reg] > val

def cmp_ge(register_file, reg, val):
    return register_file[reg] >= val

def cmp_lt(register_file, reg, val):
    return register_file[reg] < val

def cmp_le(register_file, reg, val):
    return register_file[reg] <= val

def cmp_eq(register_file, reg, val):
    return register_file[reg] == val

def cmp_ne(register_file, reg, val):
    return register_file[reg] != val

def op_inc(register_file, reg, val):
    register_file[reg] += val

def op_dec(register_file, reg, val):
    register_file[reg] -= val

op_table = {
    "inc": op_inc,
    "dec": op_dec
}

cmp_table = {
    ">":  cmp_gt,
    ">=": cmp_ge,
    "<":  cmp_lt,
    "<=": cmp_le,
    "==": cmp_eq,
    "!=": cmp_ne
}

def parse_line(line):
    dest_reg, op_str, op_val_str, _, cmp_reg, cmp_str, cmp_val_str = line.split(" ")

    op = op_table[op_str]
    op_val = int(op_val_str)
    cmp = cmp_table[cmp_str]
    cmp_val = int(cmp_val_str)
    
    return (dest_reg, op, op_val, cmp_reg, cmp, cmp_val)

def execute_line(register_file, dest_reg, op, op_val, cmp_reg, cmp, cmp_val):
    if cmp(register_file, cmp_reg, cmp_val):
        op(register_file, dest_reg, op_val)

def run_program(input_str):        
    instructions = [ parse_line(line) for line in input_str.strip().split("\n") if len(line) > 0 ]
    register_file = defaultdict(lambda: 0)
    
    for dest_reg, op, op_val, cmp_reg, cmp, cmp_val in instructions:
        execute_line(register_file, dest_reg, op, op_val, cmp_reg, cmp, cmp_val)

    return register_file
    
def largest_value(register_file):
    largest_val = -math.inf
    
    for reg in register_file.keys():
        if register_file[reg] > largest_val:
            largest_val = register_file[reg]
            
    return largest_val

# part 1 - just run and find the largest register value
def solve(input_str):
    register_file = run_program(input_str)
    return largest_value(register_file)
    
# solve(puzzle_input_test.strip())
print("part one:", solve(puzzle_input.strip()))
part one: 7787
# part 2 - largest register value we encounter during execution

def solve_part2(input_str):        
    instructions = [ parse_line(line) for line in input_str.strip().split("\n") if len(line) > 0 ]
    register_file = defaultdict(lambda: 0)
    largest_val = -math.inf
    
    for dest_reg, op, op_val, cmp_reg, cmp, cmp_val in instructions:
        execute_line(register_file, dest_reg, op, op_val, cmp_reg, cmp, cmp_val)
        largest_val_current = largest_value(register_file)
        
        if largest_val_current > largest_val:
            largest_val = largest_val_current

    return largest_val

# solve_part2(puzzle_input_test.strip())
print("part two", solve_part2(puzzle_input.strip()))
part two 8997