 The last few days I began to play around with problem 4 of Euler. I really enjoyed this problem since it dealt with a few functions in F# that I haven’t dealt with in the past.

Problem

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.

Solution

So I divided the problem up into a few functions…

reverseString simply reverses a string.

isPalindrome converts a number to a string and compares the number forwards to the number in reverse.

ProductOfNumbers is the interesting one for me – basically with my initial attempt I just generated a series of numbers and their product. The issue I was having with this approach was that it is the brute force approach, and I could not rely on the first or last palindrome to be the largest palindrome. To solve the second area of my problem I added an additional field to my solution Tuple which was the sum of x & y, because the largest sum of x & Y will result in the largest product of x & Y

``````let ProductOfNumbers num minnum =
(num, num)
|> Seq.unfold(fun(x,y)->
match y with
| y when y < minnum -> None
| y when y = x -> Some((x*y,x,y,x+y), (num,y-1))
| _ -> Some((x*y,x,y,x+y), (x-1,y))
)
|> Seq.sortBy(fun x ->
let _,_,_,key = x
-key)
``````

Finally in the res function I filter my results so that I only have palindromes and get the first one, which will be the largest one.

``````let res =
//
// Generate tuple combinations
//
ProductOfNumbers 999 100
//
// Filter out only palidromes
//
|> Seq.filter(fun x ->
let a,_,_,_ = x
isPalidrome a)
//
// Display the results
//
|> fun x ->
let a,b,c,d = x
Console.WriteLine(a.ToString() + " = " + b.ToString() + " x " + c.ToString())
``````

Whole Solution

``````open System

let reverseString (s:string) = new string(s |> Seq.toArray |> Array.rev)
let isPalidrome (x:int) =  x.ToString() = reverseString(x.ToString())

let ProductOfNumbers num minnum =
(num, num)
|> Seq.unfold(fun(x,y)->
match y with
| y when y < minnum -> None
| y when y = x -> Some((x*y,x,y,x+y), (num,y-1))
| _ -> Some((x*y,x,y,x+y), (x-1,y))
)
|> Seq.sortBy(fun x ->
let _,_,_,key = x
-key)

let res =
//
// Generate tuple combinations
//
ProductOfNumbers 999 100
//
// Filter out only palidromes
//
|> Seq.filter(fun x ->
let a,_,_,_ = x
isPalidrome a)
//
// Display the results
//
|> fun x ->
let a,b,c,d = x
Console.WriteLine(a.ToString() + " = " + b.ToString() + " x " + c.ToString())
res

``````

Conclusion

So I am aware that this does get the correct result, however I would be interested in looking at other approaches to solving this problem in F#. Any feedback / suggestions would be much appreciated.