17_crucible.py 1.2 KB

12345678910111213141516171819202122232425262728293031323334
  1. #!/usr/bin/env python3
  2. import sys
  3. from heapq import heappop, heappush
  4. def traverse(grid, minn, maxn):
  5. maxy = len(grid) - 1
  6. maxx = len(grid[0]) - 1
  7. right = 0, 0, (1, 0), 1
  8. down = 0, 0, (0, 1), 1
  9. dists = {right: 0, down: 0}
  10. work = [(0, right), (0, down)]
  11. while work:
  12. dist, key = heappop(work)
  13. x, y, direction, n = key
  14. if x == maxx and y == maxy:
  15. return dist
  16. if dist == dists[key]:
  17. prevdx, prevdy = direction
  18. for nbdir in ((-1, 0), (1, 0), (0, -1), (0, 1)):
  19. dx, dy = nbdir
  20. nx, ny = nb = x + dx, y + dy
  21. if 0 <= nx <= maxx and 0 <= ny <= maxy and \
  22. ((dx != -prevdx) if dx else (dy != -prevdy)) and \
  23. (n < maxn if nbdir == direction else n >= minn):
  24. nbdist = dist + grid[ny][nx]
  25. nbkey = nx, ny, nbdir, (n * (nbdir == direction) + 1)
  26. if nbdist < dists.get(nbkey, 1000000):
  27. dists[nbkey] = nbdist
  28. heappush(work, (nbdist, nbkey))
  29. grid = [list(map(int, line.rstrip())) for line in sys.stdin]
  30. print(traverse(grid, 1, 3))
  31. print(traverse(grid, 4, 10))