# Project Euler 4: Largest palindrome product in Functional Programming

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) {

while (true) {
const product = factor1 * factor2;
if (isSymmetric(product) && palindromeNumbers < product) {
}
if (factor1 <= 100) {
factor1 = 999;
factor2--;
} else if (factor2 <= 100) {
yield true;
} 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);
};

.value !== true) {}
.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:

1. I'm am mutating palindromeNumbers, factor1, and factor2
2. 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.

• Could you please finalize & lock down the code to review? There have been 4 edits already which makes the code under review a moving target. Dec 27, 2017 at 22:07
• @IgorSoloydenko Sorry, I thought the post is free for edit as long as no one answers it. Will make a code freeze now. Dec 27, 2017 at 22:12
• I think, you have not break any rule but it's not easy to figure out whether it's okay to start the review or not yet. :) Dec 27, 2017 at 22:23
• Hi @K. A. Buhr, I have a question maybe you can help me: How would you have solved this issue (with no libraries but vanilla JS only)? Would be interested in your approach. Thanks Jan 2, 2018 at 9:00

For the cross product I used this code snippet: https://stackoverflow.com/a/36234242

Slow as hell but seems to be fp with vanilla JS only:

/*jshint esversion: 6 */
(function () {
'use strict';
const isSymmetric = n => {
const asString = n.toString();
return asString === asString.split("")
.reverse()
.join("");
};
const range = num => Array.from(new Array(num), (_, i) => num - i);
const from999To100 = range(999)
.filter(x => x >= 100);

//https://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in-javascript/36234242#36234242
const cartesianProduct = arr => arr.reduce(
(a, b) => a.map(
x => b.map(
y => x.concat(y)))
.reduce((a, b) => a.concat(b), []), [
[]
]);

const combinations = cartesianProduct([
from999To100, from999To100
]);
const solution = combinations.map(x => x[0] * x[1])
.filter(isSymmetric)
.reduce((acc, x) => acc < x ? x : acc, 0);
console.log("solution ", solution);
})();