| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960 |
- from operator import add, mul, lt, eq
- def read_program(f):
- return list(map(int, f.readline().split(',')))
- def run(p):
- def decode_param(offset):
- return p[pc + offset], modes // (10 ** (offset - 1)) % 10
- def address(param, mode):
- addr = param + relbase * mode // 2
- if addr >= len(p):
- p.extend([0] * (addr - len(p) + 1))
- return addr
- def pload(offset):
- param, mode = decode_param(offset)
- return param if mode == 1 else p[address(param, mode)]
- def pstore(offset, value):
- param, mode = decode_param(offset)
- p[address(param, mode)] = value
- opmap = {1: add, 2: mul, 7: lt, 8: eq}
- p = list(p)
- pc = relbase = 0
- while p[pc] != 99:
- modes, opcode = divmod(p[pc], 100)
- if opcode in (1, 2, 7, 8):
- pstore(3, opmap[opcode](pload(1), pload(2)))
- pc += 4
- elif opcode == 3:
- pstore(1, (yield))
- pc += 2
- elif opcode == 4:
- yield pload(1)
- pc += 2
- elif opcode == 5:
- pc = pload(2) if pload(1) else pc + 3
- elif opcode == 6:
- pc = pload(2) if not pload(1) else pc + 3
- elif opcode == 9:
- relbase += pload(1)
- pc += 2
- def run_inputs(p, inputs):
- inputs = iter(inputs)
- computer = run(p)
- for outp in computer:
- while outp is None:
- outp = computer.send(next(inputs))
- yield outp
- def run_getter(p, get_input):
- def gen_inputs():
- while True:
- yield get_input()
- return run_inputs(p, gen_inputs())
|