13_arcade.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #!/usr/bin/env python3
  2. import sys
  3. from itertools import islice
  4. from operator import add, mul, lt, eq
  5. from time import sleep
  6. def run(p, get_input, memsize=0):
  7. def decode_param(offset):
  8. return p[pc + offset], modes // (10 ** (offset - 1)) % 10
  9. def pload(offset):
  10. param, mode = decode_param(offset)
  11. return param if mode == 1 else p[param + relbase * mode // 2]
  12. def pstore(offset, value):
  13. param, mode = decode_param(offset)
  14. p[param + relbase * mode // 2] = value
  15. opmap = {1: add, 2: mul, 7: lt, 8: eq}
  16. p = p + [0] * memsize
  17. pc = relbase = 0
  18. while p[pc] != 99:
  19. modes, opcode = divmod(p[pc], 100)
  20. if opcode in (1, 2, 7, 8):
  21. pstore(3, opmap[opcode](pload(1), pload(2)))
  22. pc += 4
  23. elif opcode == 3:
  24. pstore(1, get_input())
  25. pc += 2
  26. elif opcode == 4:
  27. yield pload(1)
  28. pc += 2
  29. elif opcode == 5:
  30. pc = pload(2) if pload(1) else pc + 3
  31. elif opcode == 6:
  32. pc = pload(2) if not pload(1) else pc + 3
  33. elif opcode == 9:
  34. relbase += pload(1)
  35. pc += 2
  36. def makegrid(game):
  37. x, y, ident = islice(game, 3)
  38. coords = []
  39. while x != -1:
  40. coords.append((x, y, ident))
  41. x, y, ident = islice(game, 3)
  42. score = ident
  43. width = max(x for x, y, ident in coords) + 1
  44. height = max(y for x, y, ident in coords) + 1
  45. grid = [[0] * width for y in range(height)]
  46. for x, y, ident in coords:
  47. grid[y][x] = ident
  48. return grid, score
  49. def draw(grid, score):
  50. print('\033c', end='')
  51. for row in grid:
  52. print(''.join(' @x_o'[c] for c in row))
  53. print('score:', score)
  54. def play(code, verbose):
  55. game = run(code, lambda: xball - xpaddle, 1000)
  56. grid, score = makegrid(game)
  57. ypaddle = next(y for y, row in enumerate(grid) if 3 in row)
  58. xball = xpaddle = 0
  59. ball_right = True
  60. if verbose:
  61. draw(grid, score)
  62. try:
  63. while True:
  64. x, y, ident = islice(game, 3)
  65. if x == -1:
  66. score = ident
  67. else:
  68. grid[y][x] = ident
  69. if ident == 3:
  70. xpaddle = x
  71. elif ident == 4:
  72. ball_right = x > xball
  73. xball = x
  74. if verbose:
  75. draw(grid, score)
  76. sleep(.003)
  77. except (StopIteration, ValueError):
  78. return score
  79. # part 1
  80. code = list(map(int, sys.stdin.read().split(',')))
  81. outp = list(run(code, lambda: 0, 1000))
  82. print(outp[2::3].count(2))
  83. # part 2
  84. code[0] = 2
  85. print(play(code, '-v' in sys.argv))