Project Euler 27

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


こうするとエラーになります。

printfn "%d" (Seq.length (Seq.takeWhile (fun n -> n < 30)
                           Seq.initInfinite (fun n -> n * n)))

どうもSequenceを束縛しなければならないようです。

let s = Seq.takeWhile (fun n -> n < 30)
                    (Seq.initInfinite (fun n -> n * n))
printfn "%d" (Seq.length s)

最初から有限列なら束縛しなくてもいいようです。

printfn "%d" (Seq.length (Seq.takeWhile (fun n -> n < 30)
                           (seq { for n in 0..10 -> n * n })))
let count n = Seq.initInfinite (fun k -> k + n)

let is_prime n =
   n >= 2 && Seq.forall (fun p -> n % p <> 0)
                  (Seq.takeWhile (fun p -> p * p <= n) (count 2))

let prime_length x =
   let a, b = x
   let s = (Seq.takeWhile is_prime
               (seq { for n in count 0 -> n * (n + a) + b }))
   Seq.length s

let N = 1000
let seq_ab = seq { for a in -N+1..N-1 do for b in 2..N+1 -> (a, b) }
let longer x y = if snd x >= snd y then x else y

printfn "%d" (fst (Seq.fold longer (0, 0)
               (Seq.map (fun x -> (fst x * snd x, prime_length x)) seq_ab)))