Wednesday, October 21, 2009

The downside of posting my solutions to the Project Euler problems is that I end up second guessing myself; "is that really the best way to solve this?" Then I have to spend some time trying alternative ideas just to convince myself that my first idea really was good enough. Often it is. Sometimes I tweak my solution to make some part of it more reusable. Reduce, recycle, reuse:


On to Project Euler problem number four:

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

I created a number of helper functions. The first takes a number and returns a sequence containing the number's digits:

let rec digits n =
    seq {
        if n > 0 then
            yield n%10
            yield! digits (n/10)
    }


The next one takes a number a reverses it (that is, 1234 would become 4321):

let reverse n =
    digits n |> Seq.fold (fun acc k -> 10*acc + k) 0


With these helpers we can easily check whether a number is a palindrome:

let palindrome n = 
    n = reverse n


So now we can create a sequence containing all the palindromes that result from multiplying two three-digit numbers together:

let palindromes = 
    seq
        for i in 1..999 do 
            for j in 1..999 do 
                if palindrome (i*j) then yield i*j 
    }


Finally we can find the largest palindrome:

palindromes |> Seq.max |> printfn "max = %A"

I think that's a pretty good solution.

No comments: