Project Euler 14

http://projecteuler.net/index.php?section=problems&id=14


コラッツの問題です。配列の要素を0にし、長さが分かるたびにそれを配列に書き込んでいきます。コラッツ列は一定の値以下なら1→2→4→1以外はループしないという実験から来る事実を使っています。
全て同じ値で配列を作るには次のようにします。

let a = Array.create 4 0   // [|0; 0; 0; 0|]

List.iterはリストの各々の要素に処理を加える関数です。

List.iter (fun i -> printf "%d " i) [ 0..3 ]    // 0 1 2 3 

関数なので値を返します。()を返すのですが、特に意識する必要も無いようです。
この問題に関しては、64ビットで計算するように書くのがめんどうです。

let N = int 1e6
let a = Array.create (N + 1) 0
a.[1] <- 1

let next n = if n % 2L = 0L then n / 2L else n * 3L + 1L
let rec collatz_length n =
      if n > int64 N || a.[int n] = 0 then (collatz_length (next n)) + 1
      else a.[int n]

List.iter (fun n -> a.[n] <- collatz_length (int64 n)) [2..N]

printfn "%d" (fst (List.maxBy snd [ for n in 2..N -> (n, a.[n]) ]))