Skipping around again, Problem 14 states:

The following iterative sequence is defined for the set of positive integers:

nn/2 (n is even)
n → 3n + 1 (n is odd)

Using the rule above and starting with 13, we generate the following sequence:

13 → 40 → 20 → 10 → 5 → 16 → 8 → 4 → 2 → 1

It can be seen that this sequence (starting at 13 and finishing at 1) contains 10 terms. Although it has not been proved yet (Collatz Problem), it is thought that all starting numbers finish at 1.

Which starting number, under one million, produces the longest chain?

I wrote a very simple implementation of this problem in F#:

let iSeq n = Seq.unfold(fun x -> if if x = 0 then None else if x = 1 then Some(x,0) else if x % 2 = 0 then Some(x,x/2) else Some(x,3*x+1)) n
let iLen n = iSeq n |> Seq.length
[for n in 1..999999 -> (n,iLen n)]
  |> List.sort(fun (_,i1) (_,i2) -> Int32.compare i2 i1)
  |> List.hd
  |> print_any;;

However, this took way too long to run, so I needed to optimize this.  Since I am only interested in the length, I can just calculate that information (I also used pattern matching instead of multiple if statements (smacking forehead on this):

#light
let seq_length l = 
    l |> 
    Seq.unfold(fun x -> 
                 match x with
                    | x when x = 0L -> None
                    | x when x = 1L -> Some((1L,0L))
                    | x when x%2L=0L -> Some((x,x/2L))
                    | _ -> Some((x,3L*x + 1L))
                    ) |> Seq.length
 
    [for i in 1L..1000000L -> (i, seq_length i)]
    |> List.fold1_left(fun (xi,xl) (i,l) -> if l > xl then (i,l) else (xi,xl) )
    |> print_any
del.icio.us Tags: ,