We draw N discs on a plane. The discs are numbered from 0 to N − 1. An array A of N non-negative integers, specifying the radiuses of the discs, is given. The J-th disc is drawn with its center at (J, 0) and radius A[J].
We say that the J-th disc and K-th disc intersect if J ≠ K and the J-th and K-th discs have at least one common point (assuming that the discs contain their borders).
The figure below shows discs drawn for N = 6 and A as follows:
A[0] = 1
A[1] = 5
A[2] = 2
A[3] = 1
A[4] = 4
A[5] = 0
There are eleven (unordered) pairs of discs that intersect, namely:
Write a function:
function solution(A);
that, given an array A describing N discs as explained above, returns the number of (unordered) pairs of intersecting discs. The function should return −1 if the number of intersecting pairs exceeds 10,000,000.
Given array A shown above, the function should return 11, as explained above.
Write an efficient algorithm for the following assumptions:
function solution(A) {
let counter = 0;
let j = 0;
let leftLimit = [];
let rightLimit = [];
//fill the left and right limits of each circle
for (var i = 0; i < A.length; i++) {
leftLimit[i] = i - A[i];
rightLimit[i] = i + A[i];
}
//sort them in an ascending order - why ?
//Basically we will rearrange their limits in an ascending way,
//we will have in leftLimit all open circles while in the right we will have where the next circle closes
leftLimit.sort((a, b) => a - b);
rightLimit.sort((a, b) => a - b);
//loop through all the elements of the RIGHT boundaries
for (var i = 0; i < A.length; i++) {
//this is the tricky part to understand
//on the left we have the boundaries of open circles, on the right the boundary of the next circle
//as long as there are circles open (rightLimit[i] >= leftLimit[j]) and (j < A.length)
while (j < A.length && rightLimit[i] >= leftLimit[j]) {
//we have circles at each position,
//so, as long as the left boundaries are smaller or equal to the right boundary, there are circles intersecting there
//if j surpasses j, it means we overcalculated and we start to decrease the number of intersections
counter += j - i;
//pass to the next open circle
j++;
}
if (counter > 10000000) return -1;
}
return counter;
}