我有一个问题:
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美元。 如果你有个好主意,请告诉我你的代码。 谢谢, 约翰
答案 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|]