Today I was doing a simple challenge on HackerRank with the code below, which is 100% acceptable and works, but I was wondering if there was a way to even further reduce the loops required by eliminating duplicate calculations.
Let me show you visually what's happening, By the time I'm done, my code example is going to be very far down!
The code takes the first number in an array of numbers and adds it to each subsequent number and checks if its divisible by k = 3.
In an array of 6 numbers, that equates to 15 loops, which would be O(n²), meaning that my loops will grow exponentially to the amount of input. 7 numbers would be 21 loops.
P.S., you might be thinking that 6 should be 21 loops, and 7 should be 28, but keep in mind that I'm always taking the current number and adding it to the next, with the exception of the last number.
Visual Breakdown
input: [1, 3, 2, 6, 1, 2]
- 1+3, 1+2, 1+6, 1+1, 1+2
- 3+2, 3+6, 3+1, 3+2
- 2+6, 2+1, 2+2
- 6+1, 6+2
- 1+2
Explanation
If you look at the numbers I've put in bold, you'll see they're duplicate calculations. The italics numbers are numbers divisible by k = 3. Now we're getting to my meat of my question. How can I eliminate this duplicate math, which would bring my loops down from 15 to 8 in this particular example. The algorithm would still have a worse case scenario of O(n²), if all the numbers were different, but this would be an optimization nonetheless.
Code Demo
function divisibleSumPairs(k, a) {
let pairs = 0;
for (let i = 0; i < a.length - 1; i++) {
for (let j = i + 1; j < a.length; j++) {
if ((a[i] + a[j])/k % 1 === 0) pairs++;
}
}
console.log(pairs);
}
divisibleSumPairs(3, [ 1, 3, 2, 6, 1, 2 ])
% 3 === 0? or what?