|
|
@@ -2,39 +2,32 @@
|
|
|
import sys
|
|
|
import re
|
|
|
|
|
|
-def ranges(sensors, y):
|
|
|
- intervals = set()
|
|
|
-
|
|
|
- def pop_overlapping(a, b):
|
|
|
- for other in intervals:
|
|
|
- c, d = other
|
|
|
- if a <= d and c <= b:
|
|
|
- intervals.remove(other)
|
|
|
- return min(a, c), max(b, d)
|
|
|
-
|
|
|
+def intervals(sensors, y):
|
|
|
for sx, sy, bx, by in sensors:
|
|
|
- dist = abs(sx - bx) + abs(sy - by) - abs(sy - y)
|
|
|
- if dist >= 0:
|
|
|
- interval = sx - dist, sx + dist
|
|
|
- new = pop_overlapping(*interval)
|
|
|
- while new:
|
|
|
- interval = new
|
|
|
- new = pop_overlapping(*interval)
|
|
|
- intervals.add(interval)
|
|
|
-
|
|
|
- return intervals
|
|
|
+ dx = abs(sx - bx) + abs(sy - by) - abs(sy - y)
|
|
|
+ if dx >= 0:
|
|
|
+ yield sx - dx, sx + dx
|
|
|
|
|
|
def coverage(sensors, y):
|
|
|
- covered = sum(r - l + 1 for l, r in ranges(sensors, y))
|
|
|
+ l, r = zip(*intervals(sensors, y))
|
|
|
beacons = len(set(bx for _, _, bx, by in sensors if by == y))
|
|
|
- return covered - beacons
|
|
|
+ return max(r) + 1 - min(l) - beacons
|
|
|
+
|
|
|
+def border(x, y, radius):
|
|
|
+ for dx in range(radius + 2):
|
|
|
+ dy = radius + 1 - dx
|
|
|
+ yield x + dx, y + dy
|
|
|
+ yield x + dx, y - dy
|
|
|
+ yield x - dx, y + dy
|
|
|
+ yield x - dx, y - dy
|
|
|
|
|
|
-def frequency(sensors, ymax):
|
|
|
- for y in range(ymax + 1):
|
|
|
- r = ranges(sensors, y)
|
|
|
- if len(r) == 2:
|
|
|
- (a, _), (b, _) = r
|
|
|
- return (max(a, b) - 1) * 4000000 + y
|
|
|
+def frequency(sensors, limit):
|
|
|
+ rad = [(sx, sy, abs(sx - bx) + abs(sy - by)) for sx, sy, bx, by in sensors]
|
|
|
+ for sensor in rad:
|
|
|
+ for x, y in border(*sensor):
|
|
|
+ if 0 <= x <= limit and 0 <= y <= limit and \
|
|
|
+ all(abs(x - sx) + abs(y - sy) > r for sx, sy, r in rad):
|
|
|
+ return x * 4000000 + y
|
|
|
|
|
|
sensors = [tuple(map(int, re.findall(r'-?\d+', line))) for line in sys.stdin]
|
|
|
print(coverage(sensors, 2000000))
|