19_beam.py 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #!/usr/bin/env python3
  2. import sys
  3. from collections import deque
  4. from itertools import islice
  5. from operator import add, mul, lt, eq
  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 deploy_drone(program, x, y):
  37. return next(run(program, [y, x].pop, 1000))
  38. def scan(program, w, h):
  39. return [[deploy_drone(program, x, y) for x in range(w)] for y in range(h)]
  40. def bounds(program):
  41. left = 0
  42. right = 1
  43. y = 0
  44. while True:
  45. yield left, right
  46. y += 1
  47. left += 1
  48. while not deploy_drone(program, left, y):
  49. left += 1
  50. right += 1
  51. while deploy_drone(program, right, y):
  52. right += 1
  53. def find_box(program, size):
  54. buf = deque([], size - 1)
  55. for y2, (left2, right2) in enumerate(bounds(program)):
  56. if len(buf) == size - 1:
  57. y1, left1, right1 = buf.popleft()
  58. if right1 - left2 >= size:
  59. return left2, y1
  60. buf.append((y2, left2, right2))
  61. # part 1
  62. program = list(map(int, sys.stdin.readline().split(',')))
  63. #print(sum(sum(row) for row in scan(program, 50, 50)))
  64. print(sum(min(r, 50) - l for l, r in islice(bounds(program), 50) if l < 50))
  65. # part 2
  66. bx, by = find_box(program, 100)
  67. print(bx * 10000 + by)