casualjavascript / blog

A collection of javascript articles stored as Github issues.
https://casualjavascript.com
MIT License
34 stars 1 forks source link

Haskell in ES6: Project Euler 1-5 #3

Open mateogianolio opened 8 years ago

mateogianolio commented 8 years ago

Originally posted 2015-11-20.

In this exercise we will use node.js 5.0.0 and

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.