Project Euler – Problem 4 Solution

Yan Cui

I help clients go faster for less using serverless technologies.

Problem

A palindromic number reads the same both ways. The largest palindrome made from the product of two 2-digit numbers is 9009 = 91 x 99.

Find the largest palindrome made from the product of two 3-digit numbers.

Solution

open System.Linq

let isPalindromic n =
    let charArray = n.ToString().ToCharArray()
    let revCharArray = Array.rev charArray
    charArray.SequenceEqual(revCharArray)

let numbers = [100..999]
let products = numbers |> List.collect (fun x -> numbers |> List.map (fun y -> x * y))
let maxPalindromic = products |> Seq.filter isPalindromic |> Seq.max

In my solution above, I first built a function to check whether a given number is palindromic by comparing the original and reversed char array representing the number and see if they’re the same, i.e. 9009 is represented by the char array [‘9′;’0′;’0′;’9’], and the reversed array is still [‘9′;’0′;’0′;’9’].

Notice how I used the Array.rev function in the isPalindromic function, it returns a new array with all the elements in reverse order. Another thing you might have noticed in this function is that I used the Enumerable.SequenceEqual Linq extension method to compare the two arrays, as I’ve mentioned before, with F# being a first class citizens of the .Net family you’re free to use whatever CLR library of your choice.

The rest of the solution might be relatively straight forward, however, you might be wondering what the List.collect function does. Like the List.map function, it applies a function to each element in the list, except that each element produces a list and all these lists are concatenated into a final list.

Now let’s see how the two differs, say we have a list of numbers from 1 to 10, and I want to find out the Cartesian product of the list multiplied by itself, i.e. 1 * 1, 1 * 2, … 1 * 10, 2 * 1, 2 * 2… 10 * 10:

let numbers = [1..10]

// List.map returns an array of array containing results of 1 *  [1..10], 2 * [1..10], etc.
numbers |> List.map (fun x -> numbers |> List.map(fun y -> x * y));;
val it : int list list =
[[1; 2; 3; 4; 5; 6; 7; 8; 9; 10];
 [2; 4; 6; 8; 10; 12; 14; 16; 18; 20];
 [3; 6; 9; 12; 15; 18; 21; 24; 27; 30];
 [4; 8; 12; 16; 20; 24; 28; 32; 36; 40];
 [5; 10; 15; 20; 25; 30; 35; 40; 45; 50];
 [6; 12; 18; 24; 30; 36; 42; 48; 54; 60];
 [7; 14; 21; 28; 35; 42; 49; 56; 63; 70];
 [8; 16; 24; 32; 40; 48; 56; 64; 72; 80];
 [9; 18; 27; 36; 45; 54; 63; 72; 81; 90];
 [10; 20; 30; 40; 50; 60; 70; 80; 90; 100]]

// List.collect returns a 1-dimensional array instead
numbers |> List.collect (fun x -> numbers |> List.map (fun y -> x * y));;
val it : int list =
[1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 2; 4; 6; 8; 10; 12; 14; 16; 18; 20; 3; 6; 9;
 12; 15; 18; 21; 24; 27; 30; 4; 8; 12; 16; 20; 24; 28; 32; 36; 40; 5; 10; 15;
 20; 25; 30; 35; 40; 45; 50; 6; 12; 18; 24; 30; 36; 42; 48; 54; 60; 7; 14;
 21; 28; 35; 42; 49; 56; 63; 70; 8; 16; 24; 32; 40; 48; 56; 64; 72; 80; 9;
 18; 27; 36; 45; 54; 63; 72; 81; 90; 10; 20; 30; 40; 50; 60; 70; 80; 90; 100]

Whenever you’re ready, here are 3 ways I can help you:

  1. Production-Ready Serverless: Join 20+ AWS Heroes & Community Builders and 1000+ other students in levelling up your serverless game.
  2. Consulting: If you want to improve feature velocity, reduce costs, and make your systems more scalable, secure, and resilient, then let’s work together and make it happen.
  3. Join my FREE Community on Skool, where you can ask for help, share your success stories and hang out with me and other like-minded people without all the negativity from social media.

 

2 thoughts on “Project Euler – Problem 4 Solution”

  1. Pingback: Project Euler — Problem 36 Solution | theburningmonk.com

  2. my solution:
    let reverseNumber n =
    let rec loop acc = function
    |0 -> acc
    |x -> loop (acc * 10 + x % 10) (x/10)
    loop 0 n

    let isPalindrome = function
    | x when x = reverseNumber x -> true
    | _ -> false

    let max =[for a in 100 .. 999 do
    for b in 100 .. 999 do yield a*b]
    |> Seq.filter (fun x -> isPalindrome x)
    |> Seq.max

Leave a Comment

Your email address will not be published. Required fields are marked *