aocpy/2018/d16.py

148 lines
2.7 KiB
Python

from lib import str_to_ints, get_data
def addr(regs, a, b, c):
regs[c] = regs[a] + regs[b]
def addi(regs, a, b, c):
regs[c] = regs[a] + b
def mulr(regs, a, b, c):
regs[c] = regs[a] * regs[b]
def muli(regs, a, b, c):
regs[c] = regs[a] * b
def banr(regs, a, b, c):
regs[c] = regs[a] & regs[b]
def bani(regs, a, b, c):
regs[c] = regs[a] & b
def borr(regs, a, b, c):
regs[c] = regs[a] | regs[b]
def bori(regs, a, b, c):
regs[c] = regs[a] | b
def setr(regs, a, _, c):
regs[c] = regs[a]
def seti(regs, a, _, c):
regs[c] = a
def gtir(regs, a, b, c):
regs[c] = 1 if a > regs[b] else 0
def gtri(regs, a, b, c):
regs[c] = 1 if regs[a] > b else 0
def gtrr(regs, a, b, c):
regs[c] = 1 if regs[a] > regs[b] else 0
def eqir(regs, a, b, c):
regs[c] = 1 if a == regs[b] else 0
def eqri(regs, a, b, c):
regs[c] = 1 if regs[a] == b else 0
def eqrr(regs, a, b, c):
regs[c] = 1 if regs[a] == regs[b] else 0
OPS = [
addr,
addi,
mulr,
muli,
banr,
bani,
borr,
bori,
setr,
seti,
gtir,
gtri,
gtrr,
eqir,
eqri,
eqrr,
]
def part_1(data):
examples = []
lines = data.splitlines()
test_prog = []
last_i = None
for i in range(len(lines)):
line = lines[i]
if line.startswith("Before:"):
regs = str_to_ints(line)
inst = str_to_ints(lines[i + 1])
regs_after = str_to_ints(lines[i + 2])
examples.append((regs, inst, regs_after))
last_i = i + 2
assert last_i is not None
for line in lines[last_i:]:
if line.strip() != "":
test_prog.append(str_to_ints(line))
r = 0
for before_orig, inst, after in examples:
ops_correct = []
for op in OPS:
before = list(before_orig)
op(before, *inst[1:])
if before == after:
ops_correct.append(op)
if len(ops_correct) >= 3:
r += 1
print(r)
code_to_op = {}
while len(OPS) > 0:
for before_orig, inst, after in examples:
ops_correct = []
for op in OPS:
before = list(before_orig)
op(before, *inst[1:])
if before == after:
ops_correct.append(op)
if len(ops_correct) == 1:
code_to_op[inst[0]] = ops_correct[0]
OPS.remove(ops_correct[0])
regs = [0, 0, 0, 0]
for line in test_prog:
op_code = line[0]
vals = line[1:]
code_to_op[op_code](regs, *vals)
print(regs[0])
def main():
data = get_data(__file__)
part_1(data)
if __name__ == "__main__":
main()