Rocket Squirrel Rocket Squirrel
Rocket Squirrel

A global community of coders, developers, and designers

November 2018
M T W T F S S
« Jul    
 1234
567891011
12131415161718
19202122232425
2627282930  

Categories


Project Euler with ES6 – Problem 1

jeffliujeffliu


wu yi

When ECMAScript 2017 was finalized in June I felt that I was not completely comfortable with the language features introduced in ECMAScript 6. ? To fix that I started solving the exercises at Project Euler using as many ES6 features as possible. This is Problem 1:

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.

Find the sum of all the multiples of 3 or 5 below 1000.

I broke this problem down into three parts:

  1. Generate the natural numbers below 1000
  2. Filter out those that are not a multiple of 3 or 5
  3. Add them together

1. Generating natural numbers

A generator is a function that pauses its own execution with the yield keyword. It is defined by putting a * after function like so:

// Natural numbers as a generator
function* naturalsGenerator() {
    let n = 1;
    while (true) {
        yield n;
        n++;
    }
}

let naturals = naturalsGenerator();
console.log(naturals.next()); // { value: 1, done: false }
console.log(naturals.next()); // { value: 2, done: false }
console.log(naturals.next()); // { value: 3, done: false }

let naturals2 = naturalsGenerator();
console.log(naturals2.next()); // { value: 1, done: false }
console.log(naturals2.next()); // { value: 2, done: false }

Natural numbers are infinite so naturalsGenerator() contains an infinite loop. The above code doesn’t run forever, however, because yield n; pauses the execution.

The let keyword is var without the hoisting.

Generators can have parameters, which is useful because the problem asks for natural numbers below 1000:

// Natural numbers as a generator with a limit parameter
function* naturals(limit) {
    for (let n = 1; n <= limit; n++) {
        yield n;
    }
}

let nat999 = [...naturals(999)];
console.log(nat999.length);

This also uses the spread operator, which here expands the contents into an array.

2. Array filtering

With an array containing the natural numbers from 1 to 999, it is time to keep the elements that are multiples of 3 or 5. Arrow functions make this more compact than was possible before:

// ES5
var old_filtered = nat999.filter(function(x) {
    return x % 3 == 0 || x % 5 == 0;
});

// ES6
let new_filtered = nat999.filter(x => x % 3 == 0 || x % 5 == 0);

More important than saving keystrokes is the way arrow functions handle the this keyword.

3. To sum up

Adding it all up can also be done with an arrow function. The final result:

// Natural numbers as a generator
function* naturals(limit) {
    for (let n = 1; n <= limit; n++) {
        yield n;
    }
}

// The sum of the multiples of 3 or 5 below 1000
console.log([...naturals(999)]
            .filter(x => x % 3 == 0 || x % 5 == 0)
            .reduce((a, b) => a + b)); // 233168

All code was tested on Node v8.1.4.

Comments 0
There are currently no comments.