19_beam.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #!/usr/bin/env python3
  2. import sys
  3. from collections import deque
  4. from operator import add, mul, lt, eq
  5. def run(p, get_input, memsize=0):
  6. def decode_param(offset):
  7. return p[pc + offset], modes // (10 ** (offset - 1)) % 10
  8. def pload(offset):
  9. param, mode = decode_param(offset)
  10. return param if mode == 1 else p[param + relbase * mode // 2]
  11. def pstore(offset, value):
  12. param, mode = decode_param(offset)
  13. p[param + relbase * mode // 2] = value
  14. opmap = {1: add, 2: mul, 7: lt, 8: eq}
  15. p = p + [0] * memsize
  16. pc = relbase = 0
  17. while p[pc] != 99:
  18. modes, opcode = divmod(p[pc], 100)
  19. if opcode in (1, 2, 7, 8):
  20. pstore(3, opmap[opcode](pload(1), pload(2)))
  21. pc += 4
  22. elif opcode == 3:
  23. pstore(1, get_input())
  24. pc += 2
  25. elif opcode == 4:
  26. yield pload(1)
  27. pc += 2
  28. elif opcode == 5:
  29. pc = pload(2) if pload(1) else pc + 3
  30. elif opcode == 6:
  31. pc = pload(2) if not pload(1) else pc + 3
  32. elif opcode == 9:
  33. relbase += pload(1)
  34. pc += 2
  35. def deploy_drone(program, x, y):
  36. return next(run(program, [y, x].pop, 1000))
  37. def scan(program, w, h):
  38. return [[deploy_drone(program, x, y) for x in range(w)] for y in range(h)]
  39. def bounds(program):
  40. left = 0
  41. right = 1
  42. y = 0
  43. while True:
  44. yield left, right
  45. y += 1
  46. left += 1
  47. while not deploy_drone(program, left, y):
  48. left += 1
  49. right += 1
  50. while deploy_drone(program, right, y):
  51. right += 1
  52. def find_box(program, size):
  53. buf = deque([], size - 1)
  54. for y2, (left2, right2) in enumerate(bounds(program)):
  55. if len(buf) == size - 1:
  56. y1, left1, right1 = buf.popleft()
  57. if right1 - left2 >= size:
  58. return left2, y1
  59. buf.append((y2, left2, right2))
  60. # part 1
  61. program = list(map(int, sys.stdin.readline().split(',')))
  62. grid = scan(program, 50, 50)
  63. print(sum(sum(row) for row in grid))
  64. # part 2
  65. bx, by = find_box(program, 100)
  66. print(bx * 10000 + by)