summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--22.22/main.py72
1 files changed, 72 insertions, 0 deletions
diff --git a/22.22/main.py b/22.22/main.py
new file mode 100644
index 0000000..a88174e
--- /dev/null
+++ b/22.22/main.py
@@ -0,0 +1,72 @@
+from sys import stdin
+import re
+
+class Wrap:
+    def __init__(self, a, b):
+        # a - first element
+        # b - length
+        self.a = a
+        self.b = b
+    def constrain(self, n):
+        return self.a + (n - self.a) % self.b
+    def __repr__(self):
+        return f"|{self.a}+{self.b}"
+
+    @staticmethod
+    def from_a(a):
+        first = 0
+        while first < len(a) and a[first].isspace():
+            first += 1
+        l = 0
+        while first + l < len(a) and not a[first + l].isspace():
+            l += 1
+        return Wrap(first, l)
+
+def rot(a):
+    target = max(map(len, a))
+    # pad
+    a = [list(r) + [' '] * (target - len(r)) for r in a]
+    return zip(*a)
+
+data = stdin.readlines()
+path = data[-1]
+data = [list(line.strip('\n')) for line in data[:-2]]
+
+rows = [Wrap.from_a(a) for a in data]
+cols = [Wrap.from_a(a) for a in rot(data)]
+
+def vis():
+    for line in data:
+        print(''.join(line))
+
+def move(facing, dist, x, y):
+    fr = ">v<^"
+    dx, dy = [(1, 0), (0, 1), (-1, 0), (0, -1)][facing % 4]
+    if dx != 0:
+        for _ in range(dist):
+            data[y][x] = fr[facing]
+            nx = rows[y].constrain(x + dx)
+            if data[y][nx] == '#':
+                break
+            x = nx
+    elif dy != 0:
+        for _ in range(dist):
+            data[y][x] = fr[facing]
+            ny = cols[x].constrain(y + dy)
+            if data[ny][x] == '#':
+                break
+            y = ny
+    return x, y
+
+def partOne():
+    x = rows[0].a
+    y = 0
+    facing = 0
+    for c in re.findall("\d+|[A-Z]", path):
+        if c == 'L': facing = (facing - 1) % 4
+        elif c == 'R': facing = (facing + 1) % 4
+        else:
+            x, y = move(facing, int(c), x, y)
+    return (y+1) * 1000 + (x+1) * 4 + facing
+
+print(partOne())