|
|
@@ -0,0 +1,85 @@
|
|
|
+#!/usr/bin/env python3
|
|
|
+import sys
|
|
|
+
|
|
|
+isa = {
|
|
|
+ 'addr': lambda a, b, reg: reg[a] + reg[b],
|
|
|
+ 'addi': lambda a, b, reg: reg[a] + b,
|
|
|
+ 'mulr': lambda a, b, reg: reg[a] * reg[b],
|
|
|
+ 'muli': lambda a, b, reg: reg[a] * b,
|
|
|
+ 'banr': lambda a, b, reg: reg[a] & reg[b],
|
|
|
+ 'bani': lambda a, b, reg: reg[a] & b,
|
|
|
+ 'borr': lambda a, b, reg: reg[a] | reg[b],
|
|
|
+ 'bori': lambda a, b, reg: reg[a] | b,
|
|
|
+ 'setr': lambda a, b, reg: reg[a],
|
|
|
+ 'seti': lambda a, b, reg: a,
|
|
|
+ 'gtir': lambda a, b, reg: int(a > reg[b]),
|
|
|
+ 'gtri': lambda a, b, reg: int(reg[a] > b),
|
|
|
+ 'gtrr': lambda a, b, reg: int(reg[a] > reg[b]),
|
|
|
+ 'eqir': lambda a, b, reg: int(a == reg[b]),
|
|
|
+ 'eqri': lambda a, b, reg: int(reg[a] == b),
|
|
|
+ 'eqrr': lambda a, b, reg: int(reg[a] == reg[b]),
|
|
|
+}
|
|
|
+
|
|
|
+def parse_insts(f):
|
|
|
+ for line in f:
|
|
|
+ opcode, operands = line[:-1].split(' ', 1)
|
|
|
+ a, b, out = map(int, operands.split())
|
|
|
+ yield opcode, a, b, out
|
|
|
+
|
|
|
+def run():
|
|
|
+ reg = [0, 0, 0, 0, 0, 0]
|
|
|
+ while reg[ip] < len(program):
|
|
|
+ opcode, a, b, out = program[reg[ip]]
|
|
|
+ reg[out] = isa[opcode](a, b, reg)
|
|
|
+ reg[ip] += 1
|
|
|
+
|
|
|
+ if reg[ip] == 28:
|
|
|
+ yield reg[4]
|
|
|
+ elif reg[ip] == 17:
|
|
|
+ reg[3] //= 256
|
|
|
+ reg[ip] = 8
|
|
|
+
|
|
|
+def simulate():
|
|
|
+ r0 = r3 = r4 = 0
|
|
|
+ while True:
|
|
|
+ r3 = r4 | 65536
|
|
|
+ r4 = 4332021
|
|
|
+
|
|
|
+ while True:
|
|
|
+ r4 = (((r4 + (r3 & 255)) & 16777215) * 65899) & 16777215
|
|
|
+
|
|
|
+ if 256 > r3:
|
|
|
+ break
|
|
|
+
|
|
|
+ # program does this loop to divide r3 by 256:
|
|
|
+ #r2 = 0
|
|
|
+ #while (r2 + 1) * 256 <= r3:
|
|
|
+ # r2 += 1
|
|
|
+ #r3 = r2
|
|
|
+
|
|
|
+ r3 //= 256
|
|
|
+
|
|
|
+ #if r4 == r0:
|
|
|
+ # break
|
|
|
+
|
|
|
+ yield r4
|
|
|
+
|
|
|
+line = sys.stdin.readline()[:-1]
|
|
|
+ip = int(line[4:])
|
|
|
+program = list(parse_insts(sys.stdin))
|
|
|
+#numbers = run()
|
|
|
+numbers = simulate()
|
|
|
+
|
|
|
+# part 1
|
|
|
+first = next(numbers)
|
|
|
+print(first)
|
|
|
+
|
|
|
+# part 2
|
|
|
+seen = set()
|
|
|
+last = first
|
|
|
+for n in numbers:
|
|
|
+ if n in seen:
|
|
|
+ break
|
|
|
+ seen.add(n)
|
|
|
+ last = n
|
|
|
+print(last)
|