Files
aocpy/2024/d18.py
2024-12-18 22:09:38 -05:00

68 lines
1.6 KiB
Python

import heapq
from lib import get_data
from lib import ints
from lib import Grid2D
data = get_data(__file__)
size = 71
grid = "\n".join(["." * size for _ in range(size)])
g = Grid2D(grid)
for i, line in enumerate(data.splitlines()):
x, y = ints(line)
g[(y, x)] = "x"
start = (0, 0)
end = (size - 1, size - 1)
def dist(n1, n2):
"""cost from node to node"""
if n1 == 0 or n1 == n2:
return 0
return 1
def h(node):
"""heuristic function (never overestimate)"""
return abs(node[0] - end[0]) + abs(node[1] - end[1])
def is_goal(node):
return node == end
def neighbors(node):
nbs = []
for nb in g.neighbors_ort(node):
if g[nb] != "x":
nbs.append(nb)
return nbs
starts = [start]
open_set = []
g_score = {}
cost = None
for start in starts:
heapq.heappush(open_set, (h(start), start))
g_score[start] = dist(0, start)
while open_set:
current_f_score, current = heapq.heappop(open_set)
if is_goal(current):
assert current_f_score == g_score[current]
cost = g_score[current]
break
for neighbor in neighbors(current):
tentative_g_score = g_score[current] + dist(current, neighbor)
if neighbor not in g_score or tentative_g_score < g_score[neighbor]:
g_score[neighbor] = tentative_g_score
f_score = g_score[neighbor] + h(neighbor)
heapq.heappush(open_set, (f_score, neighbor))
if i == 1023:
print(cost)
if cost is None:
print(line)
break