148 lines
2.7 KiB
Python
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()
|