13_arcade.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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. xpaddle = xball = 0
  59. if verbose:
  60. draw(grid, score)
  61. try:
  62. while True:
  63. x, y, ident = islice(game, 3)
  64. if x == -1:
  65. score = ident
  66. else:
  67. grid[y][x] = ident
  68. if ident == 3:
  69. xpaddle = x
  70. elif ident == 4:
  71. xball = x
  72. if verbose:
  73. draw(grid, score)
  74. sleep(.003)
  75. except (StopIteration, ValueError):
  76. return score
  77. # part 1
  78. code = list(map(int, sys.stdin.read().split(',')))
  79. outp = list(run(code, lambda: 0, 1000))
  80. print(outp[2::3].count(2))
  81. # part 2
  82. code[0] = 2
  83. print(play(code, '-v' in sys.argv))