solution.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #!/usr/bin/python3
  2. import sys
  3. from queue import Queue
  4. def print_grid(grid, as_chr=False):
  5. for row in grid:
  6. for col in row:
  7. print(chr(col) if as_chr else f'{col} ', end='')
  8. print()
  9. def find_start(grid, start):
  10. for y, row in enumerate(grid):
  11. for x, col in enumerate(row):
  12. if col == ord(start):
  13. return (x, y)
  14. return (-1, -1)
  15. def part1():
  16. start = chr(ord('a') - 1)
  17. end = chr(ord('z') + 1)
  18. grid = [[ord(c) for c in line.strip().replace('S', start).replace('E', end)] for line in sys.stdin]
  19. visited = [[False for col in row] for row in grid]
  20. steps = [[sys.maxsize for col in row] for row in grid]
  21. print_grid(grid, True)
  22. start_x, start_y = find_start(grid, start)
  23. max_x, max_y = len(grid[0]), len(grid)
  24. queue = Queue(0)
  25. #visited[start_y][start_x] = True
  26. queue.put((start_x, start_y))
  27. steps[start_y][start_x] = 0
  28. visited[start_y][start_x] = True
  29. while not queue.empty():
  30. x, y = queue.get()
  31. #print(x, y, chr(grid[y][x]))
  32. for ox, oy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
  33. nx, ny = x + ox, y + oy
  34. # skipping conditions
  35. if nx < 0 or ny < 0 or nx >= max_x or ny >= max_y:
  36. continue
  37. if grid[ny][nx] == ord(end):
  38. steps[ny][nx] = min(steps[ny][nx], steps[y][x] + 1)
  39. print(f'steps {steps[ny][nx]}')
  40. if visited[ny][nx]:
  41. #print(chr(grid[y][x]), chr(grid[ny][nx]))
  42. continue
  43. if grid[ny][nx] > grid[y][x] + 1:
  44. continue
  45. visited[ny][nx] = True
  46. steps[ny][nx] = min(steps[ny][nx], steps[y][x] + 1)
  47. queue.put((nx, ny))
  48. #print_grid(steps)
  49. # worst pathfinding code of my life
  50. # utterly lazy
  51. def part2():
  52. end = chr(ord('z') + 1)
  53. grid = [[ord(c) for c in line.strip().replace('E', end)] for line in sys.stdin]
  54. print_grid(grid, True)
  55. max_x, max_y = len(grid[0]), len(grid)
  56. starts = [[(x, y) for x, c in enumerate(row) if c == ord('a')] for y, row in enumerate(grid)]
  57. min_steps = []
  58. for row in starts:
  59. for start_x, start_y in row:
  60. #print(start_x, start_y)
  61. visited = [[False for col in row] for row in grid]
  62. steps = [[sys.maxsize for col in row] for row in grid]
  63. queue = Queue(0)
  64. #visited[start_y][start_x] = True
  65. queue.put((start_x, start_y))
  66. steps[start_y][start_x] = 0
  67. visited[start_y][start_x] = True
  68. while not queue.empty():
  69. x, y = queue.get()
  70. #print(x, y, chr(grid[y][x]))
  71. for ox, oy in [(-1, 0), (1, 0), (0, -1), (0, 1)]:
  72. nx, ny = x + ox, y + oy
  73. # skipping conditions
  74. if nx < 0 or ny < 0 or nx >= max_x or ny >= max_y:
  75. continue
  76. if grid[ny][nx] == ord(end):
  77. steps[ny][nx] = min(steps[ny][nx], steps[y][x] + 1)
  78. min_steps.append(steps[ny][nx])
  79. print(f'steps {steps[ny][nx]}')
  80. if visited[ny][nx]:
  81. #print(chr(grid[y][x]), chr(grid[ny][nx]))
  82. continue
  83. if grid[ny][nx] > grid[y][x] + 1:
  84. continue
  85. visited[ny][nx] = True
  86. steps[ny][nx] = min(steps[ny][nx], steps[y][x] + 1)
  87. queue.put((nx, ny))
  88. #print_grid(steps)
  89. print(min(min_steps))
  90. if sys.argv[1] in '1':
  91. part1()
  92. else:
  93. part2()