12_climb.py 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #!/usr/bin/env python3
  2. import sys
  3. from heapq import heappop, heappush
  4. def parse(content):
  5. grid = [ord(x) - ord('a') for x in content if x != '\n']
  6. w = content.find('\n')
  7. src = grid.index(ord('S') - ord('a'))
  8. dst = grid.index(ord('E') - ord('a'))
  9. grid[src] = 0
  10. grid[dst] = 25
  11. return grid, w, src, dst
  12. def closest_starts(grid, w, dst):
  13. h = len(grid) // w
  14. def neighbors(i):
  15. y, x = divmod(i, w)
  16. if x > 0: yield i - 1
  17. if x < w - 1: yield i + 1
  18. if y > 0: yield i - w
  19. if y < h - 1: yield i + w
  20. dist = [1 << 31] * len(grid)
  21. dist[dst] = 0
  22. worklist = [(0, dst)]
  23. while worklist:
  24. udist, u = heappop(worklist)
  25. if udist == dist[u]:
  26. for v in neighbors(u):
  27. if grid[u] <= grid[v] + 1:
  28. alt = dist[u] + 1
  29. if alt < dist[v]:
  30. dist[v] = alt
  31. heappush(worklist, (alt, v))
  32. return dist
  33. grid, w, src, dst = parse(sys.stdin.read())
  34. dist = closest_starts(grid, w, dst)
  35. print(dist[src])
  36. print(min(d for elev, d in zip(grid, dist) if not elev))