Type in the content of your page here.

This was my first version, as you can see, it is imperative and I used some printfn to do debugging. One of the bug is that the numbers can exceed 32-bit integers, thus I finally used 64-bit integers.

(* memoize function *)
open System.Collections.Generic
let memoize (f: 'a -> 'b) =
    let dict = new Dictionary<'a, 'b>()
 
    let memoizedFunc (input: 'a) =
        match dict.TryGetValue(input) with
        |true, x -> x
        |false, _ ->
            let answer = f input
            dict.Add(input, answer)
            answer
    memoizedFunc
 
let problem14 =
    let rec n3 =
        let f x = match x with
            |1L -> 1
            |n when n%2L=1L -> 1 + (n3 (3L*n+1L))
            |n -> 1+n3(n/2L)
        memoize f
 
    let rec n3iter n =
        let mutable m = n
        let mutable count = 0
        while not (m=1L) do
            //printfn "%d %d" m count
            if m%2L=1L then m <- 3L*m+1L
            else m <- m/2L
            count <- count + 1
        count
 
    let mutable best = 0
    let mutable besti = 0
    for i in 1..1000000 do
        let cnt = n3 (int64 i)
        //let cnt = n3iter (int64(i))
        if best < cnt then
            best <- cnt
            besti <- i
    besti
Let's now restructure the code in problem14 to be more functional:
let problem14b =
    let rec n3 =
        let f x = match x with
            | 1L -> 1
            | n when n%2L=1L -> 1 + (n3 (3L*n+1L))
            | n -> 1+n3(n/2L)
        memoize f
 
    {1..1000000} |> Seq.maxBy (fun n -> n3 (int64 n) )