Solve 2024 till day 18
This commit is contained in:
67
2024/d18.py
Normal file
67
2024/d18.py
Normal file
@@ -0,0 +1,67 @@
|
||||
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
|
||||
Reference in New Issue
Block a user