No puede seleccionar más de 25 temas Los temas deben comenzar con una letra o número, pueden incluir guiones ('-') y pueden tener hasta 35 caracteres de largo.

98 líneas
2.1KB

  1. from itertools import cycle
  2. SCHEME = '''
  3. ####
  4. .#.
  5. ###
  6. .#.
  7. ..#
  8. ..#
  9. ###
  10. #
  11. #
  12. #
  13. #
  14. ##
  15. ##
  16. '''
  17. def generate_blocks(scheme):
  18. blocks = []
  19. for block in scheme.strip().split('\n\n'):
  20. blocks.append(set())
  21. lns = block.splitlines()
  22. for y, row in enumerate(lns[::-1]):
  23. for x, v in enumerate(row, 2):
  24. if v == '#':
  25. blocks[-1].add(complex(x, y))
  26. return blocks
  27. def play_tetris(width, gusts, blocks, lim=None):
  28. top = 0
  29. solid = {j for j in range(width)}
  30. contribs = []
  31. block_cycle = cycle(enumerate(blocks))
  32. gust_cycle = cycle(enumerate(gusts))
  33. states = {}
  34. gust_idx = None
  35. for block_idx, block in block_cycle:
  36. # position block 4 up from top
  37. block = {(p + 1j * top) + 4j for p in block}
  38. # identify cycle
  39. if lim is None:
  40. state = tuple(complex(x, top - dy) in solid for x in range(7) for dy in range(1))
  41. key = block_idx, gust_idx, state
  42. if key in states:
  43. cycle_idx = states.get(key)
  44. return contribs[:cycle_idx], contribs[cycle_idx:]
  45. states[key] = len(states)
  46. # play
  47. for gust_idx, gust in gust_cycle:
  48. # move sideways
  49. dx = {'<': -1, '>': 1}[gust]
  50. new = {p + dx for p in block}
  51. if not any(p in solid or p.real in {-1, width} for p in new):
  52. block = new
  53. # move down
  54. dy = -1j
  55. new = {p + dy for p in block}
  56. if any(p in solid for p in new):
  57. solid |= block
  58. break
  59. else:
  60. block = new
  61. contribs.append(int(max(abs(p.imag) for p in solid)) - top)
  62. top = sum(contribs)
  63. if len(contribs) == lim:
  64. return contribs
  65. def main():
  66. width = 7
  67. gusts = open(0).read().strip()
  68. blocks = generate_blocks(SCHEME)
  69. contribs = play_tetris(width, gusts, blocks, lim=2022)
  70. print(sum(contribs))
  71. head, tail = play_tetris(width, gusts, blocks)
  72. N = 1_000_000_000_000 - len(head)
  73. print(sum(head) + sum(tail) * N // len(tail) + sum(tail[:N % len(tail)]))
  74. main()