Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
5 роки тому
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import itertools
  2. import sys
  3. from toolkit import read_image, shortest_path
  4. def move(pos):
  5. for adj in (pos + ori for ori in [1, -1, 1j, -1j]):
  6. if adj in grid:
  7. yield adj
  8. if adj in duals:
  9. yield from move(duals[adj])
  10. def move_with_depth(state):
  11. pos, level = state
  12. for adj in (pos + ori for ori in [1, -1, 1j, -1j]):
  13. if adj in inner:
  14. yield from move_with_depth((duals[adj], level + 1))
  15. elif adj in outer and (level > 0) and (grid[adj] not in {'AA', 'ZZ'}):
  16. yield from move_with_depth((duals[adj], level - 1))
  17. elif adj in grid:
  18. yield adj, level
  19. # base
  20. text = sys.stdin.read()
  21. grid = {pos: val for pos, val in read_image(text).items() if val not in ' #'}
  22. for pos, val in grid.copy().items():
  23. if val.isupper():
  24. for im in [1, 1j]:
  25. A, B, C = [pos - im, pos, pos + im]
  26. if grid.get(C) == '.':
  27. grid[B] = grid.pop(A) + grid.pop(B)
  28. if grid.get(A) == '.':
  29. grid[B] = grid.pop(B) + grid.pop(C)
  30. elements = {v: k for k, v in grid.items()}
  31. # matrix
  32. duals = {}
  33. portals = {pos for pos, cell in grid.items() if cell.isupper()}
  34. for pA, pB in itertools.combinations(portals, 2):
  35. if grid[pA] == grid[pB]:
  36. duals[pA] = pB
  37. duals[pB] = pA
  38. # part1
  39. start, end = elements['AA'], elements['ZZ']
  40. path = shortest_path(start, end, move)
  41. print(len(path) - 3)
  42. # categorize portals
  43. _, *xmid, _ = sorted({p.real for p in portals})
  44. _, *ymid, _ = sorted({p.imag for p in portals})
  45. inner = {pos for pos in portals if pos.real in xmid and pos.imag in ymid}
  46. outer = set(portals) - inner
  47. # part2
  48. start, end = (elements['AA'], 0), (elements['ZZ'], 0)
  49. path = shortest_path(start, end, move_with_depth)
  50. print(len(path) - 3)