0

この演習を解決したい: F# を使用してhttp://code.google.com/codejam/contest/351101/dashboard#s=p0 。

関数型プログラミングと F# は初めてですが、この概念と言語はとても気に入っています。そして、私はコードジャムのエクササイズも大好きです。とても簡単に見えますが、現実的です。誰かが私に解決策を指摘できますか?

現時点で、私はこのコードを書いていますが、これは単純に必須であり、機能的な観点からは見苦しく見えます:

(*
    C - Credit
    L - Items
    I - List of Integer, wher P is single integer

    How does the data look like inside file
    N
    [...
    * Money
    * Items in store
    ...]
*)

    let lines = System.IO.File.ReadAllLines("../../../../data/A-small-practice.in")
    let CBounds c = c >= 5 && c <= 1000
    let PBounds p = p >= 1 && p <= 1000

    let entries = int(lines.[0]) - 1
    let mutable index = 1   (* First index is how many entries*)
    let mutable case = 1

    for i = 0 to entries do
        let index = (i*3) + 1
        let C = int(lines.[index])
        let L = int(lines.[index+1])
        let I = lines.[index+2]    
        let items = I.Split([|' '|]) |> Array.map int    
        // C must be the sum of some items

        // Ugly imperative way which contains duplicates
        let mutable nIndex = 0
        for n in items do
            nIndex <- nIndex + 1
            let mutable mIndex = nIndex
            for m in items.[nIndex..] do            
                mIndex <- mIndex + 1
                if n + m = C then do
                    printfn "Case #%A: %A %A" case nIndex mIndex
                    case <- case + 1

C 値に加算されるが、通常の命令的な方法ではない項目を見つけたいと思います。機能的なアプローチが必要です。

4

1 に答える 1

4

問題をどのように解決するかを指定しないため、アドバイスを与えるのは困難です。

入力の読み取りに関しては、上の一連の変換として表現できますSeqSeqモジュールの高階関数は非常に便利です。

let data = 
   "../../../../data/A-small-practice.in"
   |> System.IO.File.ReadLines
   |> Seq.skip 1
   |> Seq.windowed 3
   |> Seq.map (fun lines -> let C = int(lines.[0])
                            let L = int(lines.[1])
                            let items = lines.[2].Split([|' '|]) |> Array.map int
                            (C, L, items))

アップデート:

残りの例では、シーケンス式を使用できます。ネストされた計算を表現するのに十分機能的で簡単です。

 let results = 
     seq { 
          for (C, _, items) in data do
            for j in 1..items.Length-1 do
              for i in 0..j-1 do
                if items.[j] + items.[i] = C then yield (i, j)
     }

 Seq.iteri (fun case (i, j) -> printfn "Case #%A: %A %A" case i j) results
于 2013-01-20T16:30:14.070 に答える