|
- import re
-
-
- def parse(string):
- return [int(n) for n in re.findall(r'-?\d+', string)]
-
-
- def get_parameters(ns, pos, modes, N, writes):
- for c in writes:
- # paradox: return immediate mode to use positionally outside
- modes[ord(c) - ord('a')] = '1'
-
- for mode, x in zip(modes, ns[pos:][:N]):
- yield {
- '0': lambda: ns[x],
- '1': lambda: x,
- }[mode]()
-
- yield pos + N
-
-
- def compute(ns, inp):
- if isinstance(ns, str):
- ns = parse(ns)
-
- pos = 0
- consume = lambda n, writes='': get_parameters(ns, pos, modes, n, writes)
-
- while True:
- op = ns[pos] % 100
- # instructions stupidly say ABC referring to parameters 3, 2, 1
- # we do a, b, c
- modes = list(str(ns[pos] // 100).zfill(3)[::-1])
- pos += 1
-
- if op == 1:
- a, b, c, pos = consume(3, 'c')
- ns[c] = a + b
-
- elif op == 2:
- a, b, c, pos = consume(3, 'c')
- ns[c] = a * b
-
- elif op == 3:
- a, pos = consume(1, 'a')
- ns[a] = inp
-
- elif op == 4:
- a, pos = consume(1)
- yield a
-
- elif op == 5:
- a, b, pos = consume(2)
- if a != 0:
- pos = b
-
- elif op == 6:
- a, b, pos = consume(2)
- if a == 0:
- pos = b
-
- elif op == 7:
- a, b, c, pos = consume(3, 'c')
- ns[c] = int(a < b)
-
- elif op == 8:
- a, b, c, pos = consume(3, 'c')
- ns[c] = int(a == b)
-
- elif op == 99:
- return
-
- else:
- raise RuntimeError(op)
|