Taddeus Kroes пре 6 година
родитељ
комит
4d381c4796
3 измењених фајлова са 80 додато и 0 уклоњено
  1. 40 0
      2019/23_network.py
  2. 0 0
      2019/input/23
  3. 40 0
      2019/intcode.py

+ 40 - 0
2019/23_network.py

@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+import sys
+from intcode import read_program, run_iter
+
+def run_nat(program):
+    def boot(i):
+        nic = run_iter(program, 100)
+        assert next(nic) is None
+        return nic
+
+    nics, messages = zip(*[(boot(i), [i]) for i in range(50)])
+    natpack = 0, 0
+
+    while True:
+        for i, (nic, msg) in enumerate(zip(nics, messages)):
+            msg.append(-1)
+            while msg:
+                dst = nic.send(msg.pop(0))
+                while dst is not None:
+                    pack = next(nic), next(nic)
+                    if dst == 255:
+                        natpack = pack
+                    else:
+                        messages[dst].extend(pack)
+                    dst = next(nic)
+
+        if not any(messages):
+            messages[0].extend(natpack)
+            yield natpack[1]
+
+def find_repeated_natpack(program):
+    seen = set()
+    for y in run_nat(program):
+        if y in seen:
+            return y
+        seen.add(y)
+
+program = read_program(sys.stdin)
+print(next(run_nat(program)))
+print(find_repeated_natpack(program))

Разлика између датотеке није приказан због своје велике величине
+ 0 - 0
2019/input/23


+ 40 - 0
2019/intcode.py

@@ -38,3 +38,43 @@ def run(p, get_input, memsize=0):
         elif opcode == 9:
             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

Неке датотеке нису приказане због велике количине промена