From 225fe62540df0bb072d5b8872c9131ae34d6a19c Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Sun, 16 Dec 2018 16:58:30 +1030 Subject: [PATCH] Slightly more concise 2018 Day 16 --- 2018/day16.py | 123 +++++++++----------------------------------------- 1 file changed, 22 insertions(+), 101 deletions(-) diff --git a/2018/day16.py b/2018/day16.py index b3737a3..1a52d25 100644 --- a/2018/day16.py +++ b/2018/day16.py @@ -2,118 +2,39 @@ with open('day16-input1', 'r') as file: data = [l.strip('\n') for l in file] with open('day16-input2', 'r') as file: data2 = [l.strip('\n') for l in file] -import numpy as np import re +numbers_pt1 = [[int(s) for s in re.findall(r'-?\d+', d)] for d in data if d] +numbers_pt2 = [[int(s) for s in re.findall(r'-?\d+', d)] for d in data2 if d] - -numbers = [[int(s) for s in re.findall(r'-?\d+', d)] for d in data if d] -numbers2 = [[int(s) for s in re.findall(r'-?\d+', d)] for d in data2 if d] -# arr = np.array(numbers, dtype=np.int64) - -registers = np.zeros(4, dtype=np.int64) - -def addr(regs, opcodes): +def oper_prototype(operator, immediate_a, immediate_b, regs, opcodes): op, a, b, c = opcodes r = list(regs) - r[c] = regs[a] + regs[b] + r[c] = operator((a if immediate_a else regs[a]), (b if immediate_b else regs[b])) return r -def addi(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = regs[a] + b - return r - -def mulr(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = regs[a] * regs[b] - return r - -def muli(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = regs[a] * b - return r - -def andr(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = regs[a] & regs[b] - return r - -def andi(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = regs[a] & b - return r - -def orr(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = regs[a] | regs[b] - return r - -def ori(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = regs[a] | b - return r - -def setr(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = regs[a] - return r - -def seti(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = a - return r - -def gtir(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = int(bool(a > regs[b])) - return r - -def gtri(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = int(bool(regs[a] > b)) - return r - -def gtrr(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = int(bool(regs[a] > regs[b])) - return r - -def eqir(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = int(bool(a == regs[b])) - return r - -def eqri(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = int(bool(regs[a] == b)) - return r - -def eqrr(regs, opcodes): - op, a, b, c = opcodes - r = list(regs) - r[c] = int(bool(regs[a] == regs[b])) - return r +addr = lambda regs, opcodes: oper_prototype(int.__add__, False, False, regs, opcodes) +addi = lambda regs, opcodes: oper_prototype(int.__add__, False, True, regs, opcodes) +mulr = lambda regs, opcodes: oper_prototype(int.__mul__, False, False, regs, opcodes) +muli = lambda regs, opcodes: oper_prototype(int.__mul__, False, True, regs, opcodes) +andr = lambda regs, opcodes: oper_prototype(int.__and__, False, False, regs, opcodes) +andi = lambda regs, opcodes: oper_prototype(int.__and__, False, True, regs, opcodes) +orr = lambda regs, opcodes: oper_prototype(int.__or__, False, False, regs, opcodes) +ori = lambda regs, opcodes: oper_prototype(int.__or__, False, True, regs, opcodes) +setr = lambda regs, opcodes: oper_prototype(lambda a, b: a, True, True, regs, opcodes) +seti = lambda regs, opcodes: oper_prototype(lambda a, b: a, False, True, regs, opcodes) +gtir = lambda regs, opcodes: oper_prototype(int.__gt__, True, False, regs, opcodes) +gtri = lambda regs, opcodes: oper_prototype(int.__gt__, False, True, regs, opcodes) +gtrr = lambda regs, opcodes: oper_prototype(int.__gt__, False, False, regs, opcodes) +eqir = lambda regs, opcodes: oper_prototype(int.__eq__, True, False, regs, opcodes) +eqri = lambda regs, opcodes: oper_prototype(int.__eq__, False, True, regs, opcodes) +eqrr = lambda regs, opcodes: oper_prototype(int.__eq__, False, False, regs, opcodes) instructions = [addr, addi, mulr, muli, andr, andi, orr, ori, setr, seti, gtir, gtri, gtrr, eqir, eqri, eqrr] num_3_or_more = 0 instruction_codes = {} instruction_impossibilities = {} -for before, opcodes, after in zip(numbers[::3], numbers[1::3], numbers[2::3]): +for before, opcodes, after in zip(numbers_pt1[::3], numbers_pt1[1::3], numbers_pt1[2::3]): possibilities = set() impossibilities = set() for op in instructions: @@ -151,7 +72,7 @@ while sum([len(i) for i in instruction_codes.values()]) > len(instructions): opcode_convert = {code: list(s)[0] for code, s in instruction_codes.items()} regs = [0, 0, 0, 0] -for i, opcodes in enumerate(numbers2): +for i, opcodes in enumerate(numbers_pt2): try: regs = opcode_convert[opcodes[0]](regs, opcodes) except: