I wanted to practice functional programming (fp) without using any library but pure 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 = []; while (true) { const product = factor1 * factor2; if (isSymmetric(product)) { palindromeNumbers = palindromeNumbers.concat(); } if (factor1 <= 100) { factor1 = 999; factor2 -= 1; } else if (factor2 <= 100) { yield true; return palindromeNumbers; } else { factor1 -= 1; } yield factor1 * factor2; } } 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 = Math.max(...getAllPalindromeNumbers.next() .value); console.log("solution ", solution); })()
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 the
palindromeNumbers
array and the parametersfactor1
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?