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]) ]))