| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768 |
- #!/usr/bin/env python3
- import sys
- from collections import defaultdict, deque
- def parse(f):
- def maybe_reg(op):
- return op if op.isalpha() else int(op)
- for line in f:
- parts = line.split()
- opcode = parts[0]
- a = maybe_reg(parts[1])
- b = maybe_reg(parts[2]) if len(parts) == 3 else None
- yield opcode, a, b
- def run(program, progid, part1=False):
- def value(val):
- return regs[val] if isinstance(val, str) else val
- regs = defaultdict(int)
- regs['p'] = progid
- sent = deque()
- received = deque()
- pc = 0
- while pc < len(program):
- opcode, a, b = program[pc]
- if opcode == 'snd':
- sent.append(value(a))
- elif opcode == 'set':
- regs[a] = value(b)
- elif opcode == 'add':
- regs[a] += value(b)
- elif opcode == 'mul':
- regs[a] *= value(b)
- elif opcode == 'mod':
- regs[a] %= value(b)
- elif opcode == 'rcv' and part1:
- if value(a):
- yield sent[-1]
- elif opcode == 'rcv':
- while not received:
- received = yield sent
- sent = deque()
- regs[a] = received.popleft()
- elif opcode == 'jgz' and value(a) > 0:
- pc += value(b) - 1
- pc += 1
- # part 1
- program = list(parse(sys.stdin))
- print(next(run(program, 0, True)))
- # part 2
- prog0 = run(program, 0)
- prog1 = run(program, 1)
- q0 = next(prog0)
- q1 = next(prog1)
- sent1 = len(q1)
- while q0 or q1:
- q0, q1 = prog0.send(q1), prog1.send(q0)
- sent1 += len(q1)
- print(sent1)
|