F#钱配头疼

时间:2011-11-13 21:44:38

标签: f#

我有一个问题:

let totalAmount = 1400.0M
let allocations = [| 0.45M; 0.45M; 0.1M |]
let minAmount = 250.0M

我们假设分配给3个派对有1400美元,最低分配金额为250美元;并且每一方都有不同的总金额百分比。在这里,党A& B将获得总金额的45%,而C方将获得10%,分配的金额必须是最低金额的次数。 我想写一个函数来得到结果:

let allocated = [| 500.0M; 500.0M; 250.0M |]

但我无法找到一个好方法。问题是:对于丙方来说,1400美元的10%金额仅为140美元,不到250美元,但由于甲方和乙方每人只有500美元,因此还剩下400美元,所以丙方仍然可以最低金额为250美元。 如果你有个好主意,请告诉我你的代码。 谢谢, 约翰

2 个答案:

答案 0 :(得分:2)

这个怎么样(参见内联评论中的算法描述):

let handoutMoney totalAmount allocations minAmount =
    //the general approach is to start off giving each party the 
    //minAmount, and then from there dividing up the remaining 
    //totalAmount proportionally by allocation for those parties 
    //that have not exceeded their original allocation

    //with respect to minAmount, map under-allocated as Some, 
    //and over-allocated as None
    let underAllocated =
        allocations 
        |> Array.map (fun pct -> 
            if pct * totalAmount > minAmount then Some(pct) else None)

    //Sum all the under-allocated percentages, we will use this
    //to recalculate percentages for remaining allocations beyond 
    //the minAmount
    let remainingAllocationTotal =
        underAllocated
        |> Array.sumBy (function | Some(pct) -> pct | None -> 0.0M)

    //Now using the remainingAllocationTotal we can adjust the 
    //underAllocated allocations so that the remaining amount 
    //after the min amount is subtracted can be proportionally allocated
    let remainingAllocations =
        underAllocated
        |> Array.map (function 
            | Some(pct) -> (pct / remainingAllocationTotal)
            | None -> 0.0M)

    //the amount leftover from the totalAmount after the subtracting 
    //the minAmount which was given to each party
    let remainingAmount =
        totalAmount - (minAmount * decimal allocations.Length)

    //tie it all together: add the minAmount to the remainingAllocation 
    //pct times the remainingAmount
    remainingAllocations
    |> Array.map (fun pct ->
        minAmount + (pct * remainingAmount))

然后给出你的例子,我们有:

> handoutMoney totalAmount allocations minAmount;;
val it : decimal [] =
  [|575.00000000000000000000000000M; 575.00000000000000000000000000M; 250.0M|]

(我不确定你在哪里提出500美元被分配到你的例子中的A&amp; B组,但我相信我提出的算法是我理解的问题的合理方法)< / p>

答案 1 :(得分:1)

我是F#的新手,这是我第一次尝试解决F#问题,所以请放轻松一下.. :)。嘿,但它的工作原理

<强>代码:

let HandOutMoney (totalAmount:decimal) (allocations:decimal[]) (minAmount:decimal) =
    let possibleMinimumAllocations (int) =  totalAmount/minAmount
    let allocateMoney = allocations |> Array.map(fun p ->  p * totalAmount / minAmount) |> Array.map int |> Array.map(fun x -> if x = 0 then 1 else x) |> Array.map decimal
    let finalallocateMoney = allocateMoney  |> Array.map(fun p -> p * minAmount)
    finalallocateMoney 

输入值:

let totalAmount = 1400.0M
let allocations = [| 0.45M; 0.45M; 0.1M |]
let minAmount = 250.0M

<强>输出:

HandOutMoney totalAmount allocations minAmount

val it : decimal [] = [|500.0M; 500.0M; 250.0M|]