For the Space Tyckiting event, students had to solve a small problem at the sign up. Bonus points were awarded for creativity.
If we list all the natural numbers below 10 that are multiples of 3 or 5,
we get 3, 5, 6 and 9. The sum of these multiples is 23.
Your task is to **write a function** which finds the sum of all the
multiples of 3 or 5 below 1000.
This is quite a simple task so applicants had Lazy.js and Lo-Dash libraries available to make their solutions more interesting.
The basic solution
This was a well written basic solution using for loop. There's nothing wrong with this solution, but we awarded more bonus points for creatively using provided libraries.
/* Calculates the sum of the numbers from 1 to 1000 which are
* a multiple of 3 or 5. Optimizing is trivial through precomputation:
* returning 233168 is always superior.
*/
function solution() {
var sum = 0;
// Looping through all the candidates.
for (var i = 0; i < 1000; i++) {
// Using modulo to check for the conditions.
if (i % 3 == 0 || i % 5 == 0) {
sum += i;
}
}
return sum;
}Clojure script
One applicant decided to provide a solution written in ClojureScript which was compiled to a huge blob of JS. Cool and creative.
(ns core)
(defn ^:export solution []
(reduce + (distinct (concat (range 0 1000 5) (range 0 1000 3)))))Sum minus sum of duplicates
Solution which didn't use the provided libraries but was well explained and had interesting logic behind it.
// Returns the sum of all the multiples of 3 or 5 below 1000.
// Non-generic solution.
function solution() {
var upperLimit = 1000;
// Returns an arithmetic series ranging from 0 to the largest term below
// upperLimit. diff is the difference between two consecutive terms,
// that is, the number whose multiples we are summing up.
function sumAritSeries(diff)
{
// Get the largest term of the series that is smaller than upperLimit.
var maxMultiple = diff * Math.floor((upperLimit -1)/diff);
var numTerms = maxMultiple/diff;
// The formula for an arithmetic series:
return numTerms*(maxMultiple+diff)/2;
}
// Sum up the series of 3 and 5. Substract the series of 15, as it is
// the least common multiple of 3 and 5, and thus contains all the duplicate
// terms present both in the series of 3 and 5.
return sumAritSeries(3) + sumAritSeries(5) - sumAritSeries(15);
}Array construction hacking
This answer interestingly created the array of 1000 elements. Something to
be aware of is that declaring variables without var will make them globals
by default in JS.
function solution() {
tonArray = Array.apply(null, { length: 1000 }).map(Number.call, Number);
return _.reduce(tonArray,function (sum, num) {
return sum + (num % 3 == 0 || num % 5 == 0 ? num : 0);
});
}Nice and clean
The answer used Lazy.js to solve the problem very cleanly.
function solution() {
return Lazy.range(3, 1000, 3).union(Lazy.range(5, 1000, 5)).sum();
}