| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- #!/usr/bin/env python3
- import sys
- isa = {
- 'addr': lambda a, b, reg: reg[a] + reg[b],
- 'addi': lambda a, b, reg: reg[a] + b,
- 'mulr': lambda a, b, reg: reg[a] * reg[b],
- 'muli': lambda a, b, reg: reg[a] * b,
- 'banr': lambda a, b, reg: reg[a] & reg[b],
- 'bani': lambda a, b, reg: reg[a] & b,
- 'borr': lambda a, b, reg: reg[a] | reg[b],
- 'bori': lambda a, b, reg: reg[a] | b,
- 'setr': lambda a, b, reg: reg[a],
- 'seti': lambda a, b, reg: a,
- 'gtir': lambda a, b, reg: int(a > reg[b]),
- 'gtri': lambda a, b, reg: int(reg[a] > b),
- 'gtrr': lambda a, b, reg: int(reg[a] > reg[b]),
- 'eqir': lambda a, b, reg: int(a == reg[b]),
- 'eqri': lambda a, b, reg: int(reg[a] == b),
- 'eqrr': lambda a, b, reg: int(reg[a] == reg[b]),
- }
- def run(exe, a, b, reg):
- reg = list(reg)
- reg[out] = exe(a, b, reg)
- return tuple(reg)
- # part 1
- effects, program = sys.stdin.read().rstrip().split('\n\n\n\n')
- opcodes = [set(isa.keys()) for i in range(len(isa))]
- three = 0
- for effect in effects.split('\n\n'):
- before, inst, after = effect.split('\n')
- reg = tuple(map(int, before[9:-1].split(', ')))
- opcode, a, b, out = map(int, inst.split())
- expect = tuple(map(int, after[9:-1].split(', ')))
- mnems = set(m for m, exe in isa.items() if run(exe, a, b, reg) == expect)
- opcodes[opcode] &= mnems
- three += int(len(mnems) >= 3)
- print(three)
- # part 2
- while sum(map(len, opcodes)) > len(isa):
- for opcode, mnems in enumerate(opcodes):
- if len(mnems) == 1:
- certain = next(iter(mnems))
- for other, mnems in enumerate(opcodes):
- if other != opcode:
- mnems.discard(certain)
- opcodes = [mnems.pop() for mnems in opcodes]
- reg = [0, 0, 0, 0]
- for inst in program.split('\n'):
- opcode, a, b, out = map(int, inst.split())
- reg[out] = isa[opcodes[opcode]](a, b, reg)
- print(reg[0])
|