aboutsummaryrefslogtreecommitdiff
path: root/2021/day15/15a.py
diff options
context:
space:
mode:
Diffstat (limited to '2021/day15/15a.py')
-rw-r--r--2021/day15/15a.py63
1 files changed, 63 insertions, 0 deletions
diff --git a/2021/day15/15a.py b/2021/day15/15a.py
new file mode 100644
index 0000000..d7c984b
--- /dev/null
+++ b/2021/day15/15a.py
@@ -0,0 +1,63 @@
+import heapq
+
+grid = [[int(x) for x in l] for l in open("./input").read().strip().split("\n")]
+
+def in_bounds(c):
+ x, y = c
+ return x >= 0 and y >= 0 and y < len(grid) and x < len(grid[y])
+
+def next_steps(path):
+ sx, sy = path[0]
+ for c in [(sx + 1, sy), (sx - 1, sy), (sx, sy + 1), (sx, sy - 1)]:
+ if c not in path and in_bounds(c):
+ yield c
+
+def step_path(path):
+ for c in next_steps(path):
+ yield [c] + path
+
+def total_risk(path):
+ acc = 0
+ for x, y in path:
+ if (x, y) == (0, 0):
+ continue
+ risk = grid[y][x]
+ acc += risk
+
+ return acc
+
+def manhattan(a, b):
+ dx = abs(a[0] - b[0])
+ dy = abs(a[1] - b[1])
+ return dx + dy
+
+def heuristic(path):
+ return total_risk(path) - manhattan(path[0], (len(grid), len(grid[0])))
+
+class HeapItem:
+ def __init__(self, path):
+ self.heur = heuristic(path)
+ self.path = path
+
+ def __lt__(self, other):
+ return self.heur < other.heur
+
+def find_path(start):
+ q = []
+ visited = set()
+ heapq.heappush(q, HeapItem([start]))
+ while True:
+ path = heapq.heappop(q).path
+ if path[0] == (len(grid) - 1, len(grid[0]) - 1):
+ return path
+
+ if path[0] in visited:
+ continue
+ visited.add(path[0])
+
+ for new in step_path(path):
+ heapq.heappush(q, HeapItem(new))
+
+path = find_path((0, 0))
+print(path)
+print(total_risk(path))