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) {
    let palindromeNumbers = 0;

    while (true) {
      const product = factor1 * factor2;
      if (isSymmetric(product) &amp;&amp; palindromeNumbers &lt; product) {
        palindromeNumbers = product;
      }
      if (factor1 &lt;= 100) {
        factor1 = 999;
        factor2--;
      } else if (factor2 &lt;= 100) {
        yield true;
        return palindromeNumbers;
      } else {
        factor1--;
      }
    }
  }
  const isEqual = (value, compare) =&gt; {
    if (value.length != compare.length) {
      return false;
    }
    if (value.length === 1 &amp;&amp; value[0] === compare[0]) {
      return true;
    }
    return value[0] === compare[0] &amp;&amp;
      isEqual(value.slice(1), compare.slice(1));
  };
  const isSymmetric = n =&gt; {
    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, and factor2
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.
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 =&gt; {
    const asString = n.toString();
    return asString === asString.split("")
      .reverse()
      .join("");
  };
  const range = num =&gt; Array.from(new Array(num), (_, i) =&gt; num - i);
  const from999To100 = range(999)
    .filter(x =&gt; x &gt;= 100);

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

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