22_path.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #!/usr/bin/env python3
  2. import sys
  3. def parse(inp):
  4. chartlines, pathline = inp.read().split('\n\n')
  5. chart = chartlines.split('\n')
  6. width = max(map(len, chart)) + 2
  7. chart = [' ' + line + ' ' * (width - len(line) - 1) for line in chart]
  8. chart = [' ' * width, *chart, ' ' * width]
  9. path = ''
  10. buf = ''
  11. for char in pathline:
  12. if char.isdigit():
  13. buf += char
  14. else:
  15. path += 'F' * int(buf)
  16. buf = ''
  17. if char in 'LR':
  18. path += char
  19. return chart, path
  20. def walk(chart, path, teleports={}):
  21. w = len(chart[0])
  22. h = len(chart)
  23. x, y = chart[1].index('.'), 1
  24. face = 0
  25. for step in path:
  26. if step == 'F':
  27. dx, dy = ((1, 0), (0, 1), (-1, 0), (0, -1))[face]
  28. newx = x + dx
  29. newy = y + dy
  30. newface = face
  31. if (newx, newy, face) in teleports:
  32. newx, newy, newface = teleports[(newx, newy, face)]
  33. while chart[newy][newx] == ' ':
  34. newx = (newx + dx) % w
  35. newy = (newy + dy) % h
  36. if chart[newy][newx] == '.':
  37. x = newx
  38. y = newy
  39. face = newface
  40. elif step == 'L':
  41. face = (face + 3) % 4
  42. elif step == 'R':
  43. face = (face + 1) % 4
  44. return 1000 * y + 4 * x + face
  45. RIGHT, DOWN, LEFT, UP = range(4)
  46. cube_sides = {}
  47. for y1, y2 in zip(range(1, 51), range(150, 100, -1)):
  48. cube_sides[(50, y1, LEFT)] = 1, y2, RIGHT
  49. cube_sides[(0, y2, LEFT)] = 51, y1, RIGHT
  50. cube_sides[(151, y1, RIGHT)] = 100, y2, LEFT
  51. cube_sides[(101, y2, RIGHT)] = 150, y1, LEFT
  52. for y1, x2 in zip(range(51, 101), range(1, 51)):
  53. cube_sides[(50, y1, LEFT)] = x2, 101, DOWN
  54. cube_sides[(x2, 100, UP)] = 51, y1, RIGHT
  55. for x1, y2 in zip(range(51, 101), range(151, 201)):
  56. cube_sides[(x1, 0, UP)] = 1, y2, RIGHT
  57. cube_sides[(0, y2, LEFT)] = x1, 1, DOWN
  58. for x1, x2 in zip(range(101, 151), range(1, 51)):
  59. cube_sides[(x1, 0, UP)] = x2, 200, UP
  60. cube_sides[(x2, 201, DOWN)] = x1, 1, DOWN
  61. for y1, x2 in zip(range(51, 101), range(101, 151)):
  62. cube_sides[(101, y1, RIGHT)] = x2, 50, UP
  63. cube_sides[(x2, 51, DOWN)] = 100, y1, LEFT
  64. for y1, x2 in zip(range(151, 201), range(51, 101)):
  65. cube_sides[(51, y1, RIGHT)] = x2, 150, UP
  66. cube_sides[(x2, 151, DOWN)] = 50, y1, LEFT
  67. chart, path = parse(sys.stdin)
  68. print(walk(chart, path))
  69. print(walk(chart, path, cube_sides))