|
|
@@ -1,37 +1,34 @@ |
|
|
|
import heapq |
|
|
|
|
|
|
|
|
|
|
|
def shortest_path(graph, X, Y): |
|
|
|
risk = {0: 0} |
|
|
|
seen = set() |
|
|
|
heap = [(0, '', 0)] # string disambiguates cost ties for imaginary numbers |
|
|
|
|
|
|
|
end = complex(X - 1, Y - 1) |
|
|
|
tip = 0 |
|
|
|
while end not in seen: |
|
|
|
_, _, tip = heapq.heappop(heap) |
|
|
|
seen.add(tip) |
|
|
|
for y in (tip + dx for dx in [1, -1, 1j, -1j]): |
|
|
|
if y in graph: |
|
|
|
if y not in risk or risk[y] > graph[y] + risk[tip]: |
|
|
|
risk[y] = graph[y] + risk[tip] |
|
|
|
heapq.heappush(heap, (risk[y], str(y), y)) |
|
|
|
|
|
|
|
return risk[end] |
|
|
|
def shortest_path(graph, start, end): |
|
|
|
risk_sum = {start: 0} |
|
|
|
heap = [(0, *start)] |
|
|
|
while end not in risk_sum: |
|
|
|
risk, x, y = heapq.heappop(heap) |
|
|
|
for dx, dy in [(1, 0), (-1, 0), (0, 1), (0, -1)]: |
|
|
|
adj = (x + dx, y + dy) |
|
|
|
if adj in graph: |
|
|
|
if adj not in risk_sum or risk_sum[adj] > graph[adj] + risk: |
|
|
|
risk_sum[adj] = graph[adj] + risk |
|
|
|
heapq.heappush(heap, (risk_sum[adj], x + dx, y + dy)) |
|
|
|
return risk_sum[end] |
|
|
|
|
|
|
|
|
|
|
|
graph = {} |
|
|
|
for y, line in enumerate(text.splitlines()): |
|
|
|
for y, line in enumerate(open(0).read().splitlines()): |
|
|
|
for x, char in enumerate(line): |
|
|
|
graph[complex(x, y)] = int(char) |
|
|
|
graph[x, y] = int(char) |
|
|
|
X, Y = x + 1, y + 1 |
|
|
|
|
|
|
|
ans1 = shortest_path(graph, X, Y) |
|
|
|
ans1 = shortest_path(graph, min(graph), max(graph)) |
|
|
|
print(ans1) |
|
|
|
|
|
|
|
graph = { |
|
|
|
pos + complex(X * dx, Y * dy): sum(divmod(graph[pos] + dx + dy, 10)) |
|
|
|
for pos, value in graph.items() |
|
|
|
(x + X * dx, y + Y * dy): sum(divmod(graph[x, y] + dx + dy, 10)) |
|
|
|
for (x, y), value in graph.items() |
|
|
|
for dx in range(5) |
|
|
|
for dy in range(5) |
|
|
|
} |
|
|
|
ans2 = shortest_path(graph, 5 * X, 5 * Y) |
|
|
|
ans2 = shortest_path(graph, min(graph), max(graph)) |
|
|
|
print(ans2) |