2
\$\begingroup\$

So I am once again beating a dead horse, by solving the first Project Euler problem:

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.

However, this time I am by trying to dip my toes into functional programming in javascript. I followed the following advice

no self-respecting functional programmer would be caught dead without a fold function (AKA reduce), whether she needed it or not, so let's be sure to write one now and worry about finding a way to use it later:

and added a few fold functions to my code. Any suggestions on the javascript in regards to functional programming is more than welcome. The code works as expected and returns the sum of every number bellow 1000 divisible by either 3 or 5.

I am aware that this approach is very wasteful memory wise, and it would be better simply using a for each loop.

const pipe = (...functions) => value =>
  functions.reduce((currValue, currFunc) => currFunc(currValue), value)

const range = (start, stop) => {
  return new Array(stop - start).fill().map((d, i) => i + start);
}

const divisibleByDivisors = divisors => numbers => 
   numbers.filter(num => divisors.some((divisor) => num % divisor === 0));

const addValues = (numA, numB) => numA + numB

const sumNumbers = numbers => numbers.reduce(addValues, 0)

let divisors = [3, 5]
let numbers = range(1, 1000);

const PE_001 = pipe(
  divisibleByDivisors(divisors),
  sumNumbers
)

console.log(PE_001(numbers));
\$\endgroup\$
1
  • 1
    \$\begingroup\$ No need for the helpers. This can be done as a single reduce: [...Array(1000).keys()].reduce((m,x)=> m + ((x % 3 == 0 || x % 5 == 0) ? x : 0)). \$\endgroup\$
    – Jonah
    Commented Aug 3, 2021 at 19:21

1 Answer 1

1
\$\begingroup\$

You can definitely reduce the length of some of your variable names without losing any readability:

const pipe = (...functions) => value =>
  functions.reduce((currValue, currFunc) => currFunc(currValue), value)

Could be:

const pipe = (...functions) => seed =>
  functions.reduce((value, fn) => fn(value), seed)

There's no need to add braces to your range function. As we know, all functions have one argument in FP* so I think we should do that too:

const range = start => stop => new Array(stop - start).fill().map((_, i) => i + start);

I've also used _ (sometimes called discard) to show that d isn't useful.

*I think ensuring all functions have one argument in js is painful so you probably don't really want to do this.

Some more names that might benefit from being shorter:

  • divisibleByDivisors -> isDivisibleBy
  • addValues -> add
  • sumNumbers -> sum
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.