diff options
Diffstat (limited to 'distribute.lua')
| -rw-r--r-- | distribute.lua | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/distribute.lua b/distribute.lua new file mode 100644 index 0000000..8c0b76c --- /dev/null +++ b/distribute.lua @@ -0,0 +1,48 @@ +-- min, weight, receive + +local function eliminate(budget, total_weight, elems) + if budget < 0 then + return + end + + if total_weight == 0 then + return 0 + end + + local unit = budget / total_weight + for i, e in ipairs(elems) do + local allocated = unit * e.weight + if e.min > allocated then + e.receive = e.min + table.remove(elems, i) + budget = budget - e.min + total_weight = total_weight - e.weight + return eliminate(budget, total_weight, elems) + end + end + return unit +end + +local function distribute(budget, elems) + local total_weight = 0 + local remaining = {} + for _, v in pairs(elems) do + total_weight = total_weight + v.weight + table.insert(remaining, v) + end + + local unit = eliminate(budget, total_weight, remaining) + if not unit then + for _, e in ipairs(remaining) do + e.receive = e.min + end + return false + end + + for _, e in ipairs(remaining) do + e.receive = unit * e.weight + end + return true +end + +return distribute |
