F#项目欧拉问题2

时间:2009-10-13 23:42:35

标签: f#

我对Project Euler上的problem 2解决方案的最后一步感到困惑。这是我到目前为止得到的消息来源。

#light
module pe2 (* Project Euler Problem 2 solution *)

  open System

  let Phi = 1.6180339887;;

  let invPhi = 1.0/Phi;;

  let rootOfFive = 2.236067977;;

  let maxFib = 4000000.0;

  let Fib n =
     System.Math.Round((Phi**n - invPhi**n)/rootOfFive);;

  let FibIndices = Seq.unfold(fun i -> Some(i, i+3.0)) 3.0;;

  let FibNos = FibIndices |> Seq.map(fun index -> Fib(index));;

  let setAllowedFibNos = FibNos |> Seq.filter(fun fn -> (fn <= maxFib));;

//   let answer = setAllowedFibNos |> Seq.fold (+) 0.0;

当我取消注释最后一行时,该过程似乎永远不会完成。所以我希望有人可以在正确的方向上给我一个轻柔的推动。我确实看了setAllowedFibNos并且它看起来正确但它也是一个无限序列所以我只看到前三个术语。

另外,有人能指出我将各种序列链接在一​​起的正确方法吗?我试过这样的事情:

let answer = Seq.unfold(fun i-> Some(i, i + 3.0)) 3.0 
|> Seq.map (fun index -> Fib(index))
|> Seq.filter(fun fn -> (fn <= maxFib))
|> Seq.fold (+) 0.0;;

但那没用。你可能猜到我只是在学习F#所以请温柔一点,如果之前已经问过并回答了这类问题,请发一个答案的链接,我会撤回这个。

4 个答案:

答案 0 :(得分:4)

let rec Fib(n) = 
    if (n < 2) then
        1
    else
        Fib(n-2) + Fib(n-1)

Seq.initInfinite Fib
|> Seq.takeWhile (fun a -> a <= 4000000)
|> Seq.filter (fun a -> (a % 2) = 0)
|> Seq.fold (+) 0

答案 1 :(得分:3)

'setAllowedFibNos'确实是一个无限的seq计算; 'fold'需要整个序列,因此'filter'将永远运行,寻找另一个数字&lt; = maxFib。

看看takeWhile:

http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/FSharp.Core/Microsoft.FSharp.Collections.Seq.html

我认为这是你想要的而不是过滤器。

另请注意,您可以使用'sqrt 5.0'。

答案 2 :(得分:0)

我仍然在尝试习惯Seq方法。但是,没有它,这是我的解决方案。


#light
let rec fib n =
  match n with
  |0|1 -> n
  |_ -> fib(n-1) + fib(n-2)

let maxFib = 4000000
let phi = (1.0 + sqrt(5.0)) / 2.0
let upperBound = 1 + int( log10((float(maxFib) - 0.5) * sqrt(5.0)) / log10(phi)) 

[1..upperBound] |> List.filter (fun x-> x%3=0) |> List.map fib |> List.filter (fun x -> x%2 = 0) |> List.filter (fun x -> x List.sum |> printfn "%d"

答案 3 :(得分:0)

我的解决方案是:

Seq.unfold (fun state ->
    if (fst state + snd state > 4000000) then None
    else Some(fst state + snd state, (snd state, fst state + snd state))) (0,1)
|> Seq.filter (fun x -> x % 2 = 0) 
|> Seq.sum;;