A loop is nice and all, but this problem is really just math.
We can do better and find the sum in constant time.
An arithmetic sequence is when the difference between terms is constant. For example,
1, 2, 3, 4, 5...
is an arithmetic sequence where d, the difference between terms, is 1.
0, 2, 4, 6, 8...
is an arithmetic sequence with a d of 2.
If we take a look at our sequence:
0, 3, 5, 6, 9...
we can quickly see that we have two overlapped arithmetic sequences (3n and 5n):
0, 5, 10, 15... and 0, 3, 6, 9, 12, 15...
We can then quickly see that the shared terms are those that are
multiples of 15.
Finding the sum is easier than it looks. We can use the method that
Karl Friedrich Gauss, one of the greatest mathematicians of all time, intuited
(but did not discover) at an early age (iirc, at age 6).
Let's take another look at our 3n sequence:
0, 3, 6, 9, 12, 15...
Do you see a pattern? If we draw pairs, taking a number from each end...
0 and 15
3 and 12
6 and 9
We end up with a constant sum of 15. From this, we can grok a formula.
How many pairs are there? n / 2, where n is the number of terms.
What is the sum of each pair? a1 + aN, where a1 is the first term
and aN is the last.
This means our sum is
S = (n / 2) * (a1 + aN)
We're almost there. If we add up the sums of the two sequences,
we'll get a little extra. Why?
0, 3, 6, 9, 12, 15...
0, 5, 10, 15...
We count the multiples of 15 twice! But that's easy to account for:
grandTotal = sum3 + sum5 - sum15
Our solution (you might be more interested in arithmeticProgression):
/*
finds the sum of two arithmetic sequences, on [min, max] (inclusive)
for two numbers a and b
*/
function getSum (min, max, a, b) {
function arithmeticProgression (start, stop, m) {
// find the nearest multiple of m greater than or equal to the starting bound
start = m * Math.ceil(start / m)
// find the nearest multiple of m less than or equal to the ending bound
stop = m * Math.floor(stop / m)
// the number of terms, e.g., in 0, 2, 4, 6, 8
// we have 5 terms because of (max - min)/delta + 1
// or, ((8 - 0) / 2) + 1 = 4 + 1 = 5
var terms = ((stop - start) / m) + 1
// our formula from before
return (terms / 2) * (start + stop)
}
var sum3 = arithmeticProgression(min, max, a)
var sum5 = arithmeticProgression(min, max, b)
var sum15 = arithmeticProgression(min, max, a * b)
return sum3 + sum5 - sum15
}
test:
console.log(getSum(0, 9, 3, 5) === 23) // true