【问题标题】:F# solution for Store CreditStore Credit 的 F# 解决方案
【发布时间】:2013-01-03 18:48:10
【问题描述】:

我想用 F# 解决这个练习:http://code.google.com/codejam/contest/351101/dashboard#s=p0

我是函数式编程和 F# 的新手,但我非常喜欢这个概念和语言。我也喜欢 codejam 练习,它看起来很简单,但却很真实。有人能指出我的解决方案吗?

目前我编写的这段代码只是简单的命令式,从功能的角度来看很丑:

(*
    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 值但不是以通常的命令方式的项目 - 我想要函数式方法。

【问题讨论】:

    标签: f# functional-programming


    【解决方案1】:

    你没有具体说明你将如何解决问题,所以很难给出建议。

    关于读取输入,您可以将其表示为Seq上的一系列转换。 Seq module 的高阶函数非常好用:

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

    更新:

    对于您示例的其余部分,您可以使用sequence expression。它功能强大且易于表达嵌套计算:

     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
    

    【讨论】:

    • 这真的是我想要的!看起来功能强大且易于阅读。你能给我一个完整的解决方案吗?
    • 如果你描述一下你的(甚至是命令式的)算法,我可以试一试。
    • 我已经更新了代码。它解决了问题,但不包含我想要的功能方法(用于学习目的)。
    猜你喜欢
    • 1970-01-01
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    • 2013-07-22
    • 2021-06-13
    • 1970-01-01
    • 1970-01-01
    • 2015-10-25
    相关资源
    最近更新 更多