天天看點

Project Euler -- 歐拉題集 F#(Fsharp)及Haskell 版 - No.1, No.2

最近正在看F#, 拿Project Eular來練手。

順便用Haskell做一遍,對比一下。

No1.

If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.

Find the sum of all the multiples of 3 or 5 below 1000.

F# :             [1..999]  |>  List.filter ( fun x -> (x % 3 = 0) || (x % 5 = 0) )   |>   List.sum;;

Haskell:    answer = sum . filter (\ x -> (x `mod` 3 == 0) ||  (x `mod` 5 == 0) )  $  [ 1..999 ]

Answer:    233168

後語: (.) 函數用起來比 |> 感覺好。

No2.

Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.

F#          :

let answer =

      let  d = new System.Collections.Generic.Dictionary<int,int>()

      let  rec fibCache n = if  d.ContainsKey(n) then d.[n]

                            else if n <= 2 then 1

                            else let res = fibCache (n-2) + fibCache (n-1)

                                     d.Add(n,res)

                                     res

      let rec num n = if  fibCache  n < 4000000 then num  (n + 1) else n

      let pos = num 1

      let nd  = d.Remove(pos)

      d |> Seq.map ( fun (KeyValue(k, v)) -> if v % 2 = 0 then v else 0 ) |> Seq.sum

Haskell :  --note:  效率低。 F#,将中間結果cache到一個dictionary中,速度快些。

fibPair n = foldl (\ (x,y) n -> (y, x+y) ) (1, 1)  [3..n]    

answer = sum . filter even . takeWhile ( < 4000000) . scanl ( \ acc n -> snd $ fibPair n ) 0  $  [1.. ]

Answer:    4613732

後語:F# 對象與函數式的混合,亂,不過對從imperative轉來的有親切感。