Description
Originally posted 2015-11-20
.
In this exercise we will use node.js 5.0.0 and
ƒ
for Haskell-style functions,vectorious
for creating ranges.
Install above libraries with npm:
$ npm install casualjs/f
$ npm install vectorious
Then include them in your project:
var ƒ = require('f'),
vectorious = require('vectorious');
// returns an array containing the range of numbers [m, n)
var range =
(m, n) => vectorious.Vector.range(m, n).toArray();
// will hold our answers
var ans;
A great resource for functional problems is Project Euler,
so let's go ahead and solve the first five problems.
Full source is available in this GitHub repo.
Most of the code is self-explanatory, but you should at least have knowledge of basic Array
operations (i.e. map
, reduce
, filter
, forEach
, concat
) and how to use them.
Multiples of 3 and 5
Find the sum of all the multiples of 3 or 5 below 1000.
// add two numbers
var add =
(a, b) => a + b;
// check if number is multiple of 5 or 3
var multiple =
(x) => (x % 5 === 0 || x % 3 === 0);
ans = range(0, 1000)
.filter(multiple)
.reduce(add);
console.log('Multiples of 3 and 5:', ans);
Even fibonacci numbers
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
// check if number is even
var even =
(x) => x % 2 === 0;
var fib = [1, 2];
while (ƒ.last(fib) < 4000000)
fib = ƒ.concat([1, 2], ƒ.zipWith(add, fib, ƒ.tail(fib)));
ans = fib
.filter(even)
.reduce(add);
console.log('Even fibonacci numbers:', ans);
Largest prime factor
What is the largest prime factor of the number 600851475143?
// integer square root
var isqrt =
(x) => Math.floor(Math.sqrt(x));
// integer division
var idiv =
(a, b) => Math.floor(a / b);
// check n mod x
var mod =
(n) => (x) => n % x === 0;
// get prime factors from arbitrary number
var factors =
(n) => {
var prime = ƒ.take(1, range(2, isqrt(n) + 2).filter(mod(n)));
if (!prime.length)
return n === 1 ? [] : [n];
return prime.concat(factors(idiv(n, prime)));
};
ans = ƒ.last(factors(600851475143));
console.log('Largest prime factor:', ans);
Largest palindrome product
Find the largest palindrome made from the product of two 3-digit numbers.
// check if number is palindrome
var palindrome =
(n) => n === parseInt(('' + n).split('').reverse().join(''));
ans = [];
range(100, 1000).forEach(
x => range(x, 1000).forEach(
y => ans.push(x * y)
)
);
ans = Math.max(...ans.filter(palindrome));
console.log('Largest palindrome product:', ans);
Smallest multiple
What is the smallest positive number that is evenly divisible by all of the numbers from 1 to 20?
// product of two numbers
var product =
(a, b) => a * b;
// reduce an array of arrays with product
var productReduce =
(xs) => xs.reduce(product);
// check if array is homogeneous
// i.e. [2, 2, 2] is homogeneous, [2, 2, 3] is not.
var homogeneous =
(xs) => ƒ.head(xs) === ƒ.last(xs);
// if array contains duplicates with differing lengths,
// keep the one that is longest
// i.e. if array contains [2], [2, 2] and [2, 2, 2] only keep [2, 2, 2]
var duplicates =
(xs, _, self) =>
self.filter(
(ys) =>
ƒ.head(xs) === ƒ.head(ys) &&
xs.length < ys.length
).length ?
false : true;
ans = range(2, 20)
.map(factors)
.filter(homogeneous)
.filter(duplicates)
.map(productReduce)
.reduce(product);
console.log('Smallest multiple:', ans);
I've added a comment section below where you can ask questions or highlight any
errors with the code.