I wanted to practice functional programming (fp) without using any library but using vanilla JS only. So I took the 4th problem from project euler:
A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 × 99.
Find the largest palindrome made from the product of two 3-digit numbers.
My solution in fp looks like this:
/*jshint esversion: 6 */
(function () {
'use strict';
function* multiply(factor1, factor2) {
let palindromeNumbers = 0;
while (true) {
const product = factor1 * factor2;
if (isSymmetric(product) && palindromeNumbers < product) {
palindromeNumbers = product;
}
if (factor1 <= 100) {
factor1 = 999;
factor2--;
} else if (factor2 <= 100) {
yield true;
return palindromeNumbers;
} else {
factor1--;
}
}
}
const isEqual = (value, compare) => {
if (value.length != compare.length) {
return false;
}
if (value.length === 1 && value[0] === compare[0]) {
return true;
}
return value[0] === compare[0] &&
isEqual(value.slice(1), compare.slice(1));
};
const isSymmetric = n => {
const asArray = n.toString()
.split('');
const mid = Math.floor(asArray.length / 2);
const half1 = asArray.slice(0, mid);
const half2 = asArray.slice(asArray.length - mid)
.reverse();
return isEqual(half1, half2);
};
const getAllPalindromeNumbers = multiply(999, 999);
while (getAllPalindromeNumbers.next()
.value !== true) {}
const solution = getAllPalindromeNumbers.next()
.value;
})();
First I wanted to solve this using recursion. But I reached the stack size pretty quickly. Therefore I opted for generators. But I'm not satisfied with my solution especially because of the multiply generator:
- I'm am mutating
palindromeNumbers,factor1, andfactor2 - I'm using a while loop twice
Is it possible to solve this problem yet still be consistent with fp, i.e. no mutations and no loops? And of course: Any other improvement suggestions are welcomed.