AoC2024 day10
authorPat Thoyts <pat.thoyts@gmail.com>
Wed, 11 Dec 2024 00:39:36 +0000 (00:39 +0000)
committerPat Thoyts <pat.thoyts@gmail.com>
Wed, 11 Dec 2024 00:39:36 +0000 (00:39 +0000)
day10/__init__.py [new file with mode: 0644]
day10/__main__.py [new file with mode: 0644]

diff --git a/day10/__init__.py b/day10/__init__.py
new file mode 100644 (file)
index 0000000..43a42d8
--- /dev/null
@@ -0,0 +1,57 @@
+from dataclasses import dataclass
+from typing import List, Tuple
+
+LEFT = (0, -1)
+UP = (-1, 0)
+RIGHT = (0, 1)
+DOWN = (1, 0)
+
+
+@dataclass
+class Problem:
+    data: List[List[int]]
+
+    def trailheads(self):
+        for row, values in enumerate(self.data):
+            for col, value in enumerate(values):
+                if value == 0:
+                    yield (row, col)
+
+    def score(self, head: Tuple[int, int]) -> List[Tuple[int, int]]:
+        score = []
+        rows, cols = len(self.data), len(self.data[0])
+        val = self.data[head[0]][head[1]]
+        if val < 9: 
+            nextval = val + 1
+            for dir in (LEFT, UP, RIGHT, DOWN):
+                row = head[0] + dir[0]
+                col = head[1] + dir[1]
+                if row >= 0 and row < rows and col >= 0 and col < cols:
+                    if self.data[row][col] == nextval:
+                        score += self.score((row, col))
+        else:
+            return [head]
+        return score
+
+    def run(self, part2: bool = False, debug: bool = False) -> int:
+        result = {}
+        rows, cols = len(self.data), len(self.data[0])
+        for head in self.trailheads():
+            if part2:
+                result[head] = self.score(head)
+            else:
+                result[head] = set(self.score(head))
+
+        sum = 0
+        for k in result:
+            sum += len(result[k])
+            if debug:
+                print('for head', k, ' score ', len(result[k]), result[k])
+        return sum
+
+    @staticmethod
+    def from_stream(stream) -> 'Problem':
+        data = []
+        for line in stream:
+            data.append([int(x) for x in line.strip()])
+        return Problem(data)
diff --git a/day10/__main__.py b/day10/__main__.py
new file mode 100644 (file)
index 0000000..344c92a
--- /dev/null
@@ -0,0 +1,24 @@
+import sys
+import argparse
+from . import Problem
+
+
+def main(args=None):
+    parser = argparse.ArgumentParser(description="AOC 2024 day 10")
+    parser.add_argument('filename', type=str)
+    parser.add_argument('-d', '--debug', action='store_true')
+    parser.add_argument('-2', '--part2', action='store_true')
+    options = parser.parse_args(args)
+
+    with open(options.filename) as f:
+        problem = Problem.from_stream(f)
+    if options.debug:
+        for row in problem.data:
+            print(row)
+
+    print(f"result {problem.run(part2=options.part2, debug=options.debug)}")
+    return 0
+
+
+if __name__ == '__main__':
+    sys.exit(main(sys.argv[1:]))