15.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. from util import get_input
  2. from queue import PriorityQueue
  3. input = get_input("15.input")
  4. def add(a, b):
  5. return tuple(map(lambda i, j: i + j, a, b))
  6. def grid_size(grid):
  7. x = max([x for (x, y) in grid.keys()])
  8. y = max([y for (x, y) in grid.keys()])
  9. return (x + 1, y + 1)
  10. def print_grid(grid):
  11. sz = grid_size(grid)
  12. for y in range(sz[1]):
  13. print("".join(str(grid[(x, y)]) for x in range(sz[0])))
  14. def neighbors(pos, sz):
  15. ns = [add(pos, dpos) for dpos in [(1, 0), (-1, 0), (0, 1), (0, -1)]]
  16. return [n for n in ns if n[0] >= 0 and n[0] < sz[0] and n[1] >= 0 and n[1] < sz[1]]
  17. def cheapest_path(grid):
  18. sz = grid_size(grid)
  19. maxpos = (sz[0] - 1, sz[1] - 1)
  20. cost = {(0, 0): 0}
  21. queue = PriorityQueue()
  22. queue.put((0, (0, 0)))
  23. while not queue.empty():
  24. prio, current = queue.get()
  25. if current == maxpos:
  26. return prio
  27. for n in neighbors(current, sz):
  28. if cost[current] + grid[n] < cost.get(n, 10000000000):
  29. cost[n] = cost[current] + grid[n]
  30. queue.put((cost[n], n))
  31. grid = {}
  32. for y, line in enumerate(input):
  33. for x, c in enumerate(line):
  34. grid[(x, y)] = int(c)
  35. print("Part 1:", cheapest_path(grid))
  36. sz = grid_size(grid)
  37. for x in range(sz[0]):
  38. for y in range(sz[1]):
  39. for mx in range(1, 5):
  40. val = grid[(x, y)] + mx
  41. if val > 9:
  42. val -= 9
  43. grid[(x + mx * sz[0], y)] = val
  44. sz = grid_size(grid)
  45. for x in range(sz[0]):
  46. for y in range(sz[1]):
  47. for my in range(1, 5):
  48. val = grid[(x, y)] + my
  49. if val > 9:
  50. val -= 9
  51. grid[(x, y + my * sz[1])] = val
  52. print("Part 2:", cheapest_path(grid))