|
|
@@ -3,20 +3,26 @@ from operator import add, mul, lt, eq
|
|
|
def read_program(f):
|
|
|
return list(map(int, f.readline().split(',')))
|
|
|
|
|
|
-def run(p, get_input, memsize=0):
|
|
|
+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[param + relbase * mode // 2]
|
|
|
+ return param if mode == 1 else p[address(param, mode)]
|
|
|
|
|
|
def pstore(offset, value):
|
|
|
param, mode = decode_param(offset)
|
|
|
- p[param + relbase * mode // 2] = value
|
|
|
+ p[address(param, mode)] = value
|
|
|
|
|
|
opmap = {1: add, 2: mul, 7: lt, 8: eq}
|
|
|
- p = p + [0] * memsize
|
|
|
+ p = list(p)
|
|
|
pc = relbase = 0
|
|
|
|
|
|
while p[pc] != 99:
|
|
|
@@ -26,7 +32,7 @@ def run(p, get_input, memsize=0):
|
|
|
pstore(3, opmap[opcode](pload(1), pload(2)))
|
|
|
pc += 4
|
|
|
elif opcode == 3:
|
|
|
- pstore(1, get_input())
|
|
|
+ pstore(1, (yield))
|
|
|
pc += 2
|
|
|
elif opcode == 4:
|
|
|
yield pload(1)
|
|
|
@@ -39,42 +45,16 @@ def run(p, get_input, memsize=0):
|
|
|
relbase += pload(1)
|
|
|
pc += 2
|
|
|
|
|
|
-def run_iter(p, memsize=0):
|
|
|
- def decode_param(offset):
|
|
|
- return p[pc + offset], modes // (10 ** (offset - 1)) % 10
|
|
|
-
|
|
|
- def pload(offset):
|
|
|
- param, mode = decode_param(offset)
|
|
|
- return param if mode == 1 else p[param + relbase * mode // 2]
|
|
|
-
|
|
|
- def pstore(offset, value):
|
|
|
- param, mode = decode_param(offset)
|
|
|
- p[param + relbase * mode // 2] = value
|
|
|
-
|
|
|
- opmap = {1: add, 2: mul, 7: lt, 8: eq}
|
|
|
- p = p + [0] * memsize
|
|
|
- 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:
|
|
|
- inp = (yield)
|
|
|
- #print('inp', inp)
|
|
|
- pstore(1, inp)
|
|
|
- pc += 2
|
|
|
- elif opcode == 4:
|
|
|
- outp = pload(1)
|
|
|
- #print('outp', outp)
|
|
|
- yield outp
|
|
|
- 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())
|