|
|
@@ -3,11 +3,13 @@ import itertools |
|
|
|
import re |
|
|
|
|
|
|
|
|
|
|
|
def parse(string): |
|
|
|
ns = [int(n) for n in re.findall(r'-?\d+', string)] |
|
|
|
memory = collections.defaultdict(int) |
|
|
|
memory.update(enumerate(ns)) |
|
|
|
return memory |
|
|
|
MODES = { |
|
|
|
'0': lambda ns, x, relbase: ns[x], |
|
|
|
'1': lambda ns, x, relbase: x, |
|
|
|
'2': lambda ns, x, relbase: ns[x + relbase], |
|
|
|
'0-special': lambda ns, x, relbase: x, |
|
|
|
'2-special': lambda ns, x, relbase: x + relbase, |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
def get_parameters(ns, pos, modes, N, writes, relbase): |
|
|
@@ -15,16 +17,10 @@ def get_parameters(ns, pos, modes, N, writes, relbase): |
|
|
|
# paradox: return immediate mode to use positionally outside |
|
|
|
modes[ord(c) - ord('a')] += '-special' |
|
|
|
|
|
|
|
for mode, x in zip(modes, [ns[y] for y in range(pos, pos + N)]): |
|
|
|
yield { |
|
|
|
'0': lambda: ns[x], |
|
|
|
'1': lambda: x, |
|
|
|
'2': lambda: ns[x + relbase], |
|
|
|
'0-special': lambda: x, |
|
|
|
'2-special': lambda: x + relbase, |
|
|
|
}[mode]() |
|
|
|
|
|
|
|
yield pos + N |
|
|
|
for i in range(N): |
|
|
|
mode, x = modes[i], ns[pos + i] |
|
|
|
yield MODES[mode](ns, x, relbase) |
|
|
|
|
|
|
|
|
|
|
|
def compute(ns, in_iter): |
|
|
@@ -43,45 +39,45 @@ def compute(ns, in_iter): |
|
|
|
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]) |
|
|
|
modes = list(str(ns[pos] // 100)[::-1] + '000') |
|
|
|
pos += 1 |
|
|
|
|
|
|
|
if op == 1: |
|
|
|
a, b, c, pos = consume(3, 'c') |
|
|
|
pos, a, b, c = consume(3, 'c') |
|
|
|
ns[c] = a + b |
|
|
|
|
|
|
|
elif op == 2: |
|
|
|
a, b, c, pos = consume(3, 'c') |
|
|
|
pos, a, b, c = consume(3, 'c') |
|
|
|
ns[c] = a * b |
|
|
|
|
|
|
|
elif op == 3: |
|
|
|
a, pos = consume(1, 'a') |
|
|
|
pos, a = consume(1, 'a') |
|
|
|
ns[a] = next(in_iter) |
|
|
|
|
|
|
|
elif op == 4: |
|
|
|
a, pos = consume(1) |
|
|
|
pos, a = consume(1) |
|
|
|
yield a |
|
|
|
|
|
|
|
elif op == 5: |
|
|
|
a, b, pos = consume(2) |
|
|
|
pos, a, b = consume(2) |
|
|
|
if a != 0: |
|
|
|
pos = b |
|
|
|
|
|
|
|
elif op == 6: |
|
|
|
a, b, pos = consume(2) |
|
|
|
pos, a, b = consume(2) |
|
|
|
if a == 0: |
|
|
|
pos = b |
|
|
|
|
|
|
|
elif op == 7: |
|
|
|
a, b, c, pos = consume(3, 'c') |
|
|
|
pos, a, b, c = consume(3, 'c') |
|
|
|
ns[c] = int(a < b) |
|
|
|
|
|
|
|
elif op == 8: |
|
|
|
a, b, c, pos = consume(3, 'c') |
|
|
|
pos, a, b, c = consume(3, 'c') |
|
|
|
ns[c] = int(a == b) |
|
|
|
|
|
|
|
elif op == 9: |
|
|
|
a, pos = consume(1) |
|
|
|
pos, a = consume(1) |
|
|
|
relbase += a |
|
|
|
|
|
|
|
elif op == 99: |
|
|
@@ -89,3 +85,10 @@ def compute(ns, in_iter): |
|
|
|
|
|
|
|
else: |
|
|
|
raise RuntimeError(op) |
|
|
|
|
|
|
|
|
|
|
|
def parse(string): |
|
|
|
ns = [int(n) for n in re.findall(r'-?\d+', string)] |
|
|
|
memory = collections.defaultdict(int) |
|
|
|
memory.update(enumerate(ns)) |
|
|
|
return memory |