#!/usr/bin/env python3 from itertools import product from operator import mul, add def primitive(operator): def opcode(program, i): val = lambda x: program[program[x]] program[program[i+3]] = operator(val(i+1), val(i+2)) return i+4 return opcode opcodes = {1 : primitive(add), 2 : primitive(mul), 99 : lambda p, i: len(p) } def interpret(program): i = 0 while i < len(program): op = program[i] i = opcodes[op](program, i) return program def preproc(puzzle_input): program = list(map(int, puzzle_input.split(','))) init_prog = lambda a,b: program[:1] + [a, b] + program[3:] return init_prog def partI(init_prog): end_state = interpret(init_prog(12, 2)) return end_state[0] def partII(init_prog): target = 19690720 space = 2 * list(range(100)) for noun, verb in product(space, space): memory = init_prog(noun, verb) end_state = interpret(memory) if end_state[0] == target: break return 100*noun + verb