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