Răsfoiți Sursa

Retrofit new intcode interpreter into older challenges

Taddeus Kroes 6 ani în urmă
părinte
comite
cae5fd2930
2 a modificat fișierele cu 39 adăugiri și 49 ștergeri
  1. 15 15
      2019/09_boost.py
  2. 24 34
      2019/11_paintrobot.py

+ 15 - 15
2019/09_boost.py

@@ -2,7 +2,18 @@
 import sys
 from operator import add, mul, lt, eq
 
-def run(p, inputs, memsize=0):
+def run(p, get_input, 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
@@ -10,22 +21,11 @@ def run(p, inputs, memsize=0):
     while p[pc] != 99:
         modes, opcode = divmod(p[pc], 100)
 
-        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
-
         if opcode in (1, 2, 7, 8):
             pstore(3, opmap[opcode](pload(1), pload(2)))
             pc += 4
         elif opcode == 3:
-            pstore(1, inputs.pop())
+            pstore(1, get_input())
             pc += 2
         elif opcode == 4:
             yield pload(1)
@@ -39,5 +39,5 @@ def run(p, inputs, memsize=0):
             pc += 2
 
 program = list(map(int, sys.stdin.read().split(',')))
-print(next(run(program, [1], 10000)))
-print(next(run(program, [2], 10000)))
+print(next(run(program, [1].pop, 10000)))
+print(next(run(program, [2].pop, 10000)))

+ 24 - 34
2019/11_paintrobot.py

@@ -2,7 +2,18 @@
 import sys
 from operator import add, mul, lt, eq
 
-def run(p, inputs, memsize=0):
+def run(p, get_input, 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
@@ -10,25 +21,14 @@ def run(p, inputs, memsize=0):
     while p[pc] != 99:
         modes, opcode = divmod(p[pc], 100)
 
-        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
-
         if opcode in (1, 2, 7, 8):
             pstore(3, opmap[opcode](pload(1), pload(2)))
             pc += 4
         elif opcode == 3:
-            pstore(1, inputs.pop())
+            pstore(1, get_input())
             pc += 2
         elif opcode == 4:
-            inputs = yield pload(1) or inputs
+            yield pload(1)
             pc += 2
         elif opcode == 5:
             pc = pload(2) if pload(1) else pc + 3
@@ -38,30 +38,20 @@ def run(p, inputs, memsize=0):
             relbase += pload(1)
             pc += 2
 
-def paint(firmware, startcolor):
-    robot = run(firmware, [startcolor], 1000)
+def paint(firmware, color):
+    robot = run(firmware, lambda: color, 1000)
     painted = set()
     white = set()
-    inputs = None
     x = y = 0
     dx, dy = 0, -1
-    try:
-        while True:
-            make_white = robot.send(inputs)
-            painted.add((x, y))
-            (white.add if make_white else white.discard)((x, y))
-
-            right = next(robot)
-            if right:
-                dx, dy = -dy, dx
-            else:
-                dx, dy = dy, -dx
-            x += dx
-            y += dy
-
-            inputs = [int((x, y) in white)]
-    except StopIteration:
-        return white, len(painted)
+    for make_white in robot:
+        painted.add((x, y))
+        (white.add if make_white else white.discard)((x, y))
+        dx, dy = (-dy, dx) if next(robot) else (dy, -dx)
+        x += dx
+        y += dy
+        color = int((x, y) in white)
+    return white, len(painted)
 
 def draw(coords):
     xmin = min(x for x, y in coords)