···11+import fileinput
22+import heapq
33+from utils import Point
44+55+66+def shortest_path(graph, start, end):
77+ """Returns the shortest path from start to end in graph."""
88+ horizon = [(0, start)]
99+ seen = set()
1010+1111+ while horizon:
1212+ depth, node = heapq.heappop(horizon)
1313+1414+ if node == end:
1515+ return depth
1616+ elif node in seen:
1717+ continue
1818+1919+ seen.add(node)
2020+2121+ for neigh in node.neighbours_4():
2222+ if neigh not in graph:
2323+ continue
2424+2525+ heapq.heappush(horizon, (depth + graph[neigh], neigh))
2626+2727+ return -1
2828+2929+3030+CAVE = {}
3131+3232+# Read problem input and solve part 1.
3333+for y, line in enumerate(fileinput.input()):
3434+ for x, c in enumerate(line.strip()):
3535+ CAVE[Point(x, y)] = int(c)
3636+ WIDTH = x + 1
3737+3838+ HEIGHT = y + 1
3939+4040+print "Part 1:", shortest_path(CAVE, Point(0, 0), Point(x, y))
4141+4242+4343+# Replicate CAVE tiles to solve part 2.
4444+for y in range(HEIGHT*5):
4545+ for x in range(WIDTH*5):
4646+ if Point(x, y) not in CAVE:
4747+ dx = x // WIDTH
4848+ dy = y // HEIGHT
4949+5050+ # Need to subtract one, take modulo, then add one because we
5151+ # are dealing with the range 1-9, not 0-8.
5252+ val = (CAVE[Point(x % WIDTH, y % HEIGHT)] + (dx + dy))
5353+ CAVE[Point(x, y)] = ((val - 1) % 9) + 1
5454+5555+print "Part 2:", shortest_path(CAVE, Point(0, 0), Point(x, y))