function numEmpty(sensors, row) {
const extents = sensors
.filter(([sx, sy, bx, by]) => Math.abs(sy - row) <= dist([sx, sy, bx, by]))
.map(([sx, sy, bx, by]) => {
const halfWidth = dist([sx, sy, bx, by]) - Math.abs(sy - row);
return [sx - halfWidth, sx + halfWidth];
})
.sort((a, b) => a[0] - b[0]);
let [left, right, n] = [extents[0][0], extents[0][1], 0];
extents.push([Infinity, Infinity]);
for (const extent of extents) {
const [start, end] = extent;
if (start <= right) {
right = Math.max(right, end);
} else {
n += right - left + 1;
[left, right] = start === Infinity ? [left, right] : [start, end];
}
}
const numBeaconsInRow = sensors.reduce(
(beacons, [sx, sy, bx, by]) => (by === row ? beacons.add(bx) : beacons),
new Set()
).size;
return n - numBeaconsInRow;
}