15_beacon.py 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #!/usr/bin/env python3
  2. import sys
  3. import re
  4. def ranges(sensors, y):
  5. intervals = set()
  6. def pop_overlapping(a, b):
  7. for other in intervals:
  8. c, d = other
  9. if a <= d and c <= b:
  10. intervals.remove(other)
  11. return min(a, c), max(b, d)
  12. for sx, sy, bx, by in sensors:
  13. dist = abs(sx - bx) + abs(sy - by) - abs(sy - y)
  14. if dist >= 0:
  15. interval = sx - dist, sx + dist
  16. new = pop_overlapping(*interval)
  17. while new:
  18. interval = new
  19. new = pop_overlapping(*interval)
  20. intervals.add(interval)
  21. return intervals
  22. def coverage(sensors, y):
  23. covered = sum(r - l + 1 for l, r in ranges(sensors, y))
  24. beacons = len(set(bx for _, _, bx, by in sensors if by == y))
  25. return covered - beacons
  26. def frequency(sensors, ymax):
  27. for y in range(ymax + 1):
  28. r = ranges(sensors, y)
  29. if len(r) == 2:
  30. (a, _), (b, _) = r
  31. return (max(a, b) - 1) * 4000000 + y
  32. sensors = [tuple(map(int, re.findall(r'-?\d+', line))) for line in sys.stdin]
  33. print(coverage(sensors, 2000000))
  34. print(frequency(sensors, 4000000))