HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavascriptMinor

Function that divides money with regard to the smallest denomination

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
regardmoneysmallestthewithfunctiondividesthatdenomination

Problem

I'm writing a function divideMoney that takes the value of a sum of money and divides it according to some percentages, then rounds each division to the nearest denomination.

For example:

//divideMoney(sum, percentages, denomination);

divideMoney(102, [0.5, 0.30, 0.20], 0.25);


This should divide the sum of $102 to 3 divisions, first is 50% ($51), second is 30% ($30.6) and the third is 20% ($20.4).

But because the smallest accepted denomination is the quarter ( 0.25 ), so $30.6 should be $30.50 instead, and $20.40 should be $20.50 as well. So the expected result is [51, 30.5, 20.5].

Here is what I tried

Original Code

function divideMoney(sum, percentages, denomination) {
    var result, diff, resultSum;
    result = [];
    diff = 0;
    percentages.forEach(function (percent) {
        var div, fraction, mod;
        div = (percent * sum) + diff;
        fraction = div - Math.trunc(div);
        if (fraction > 0) {
            mod = fraction % denomination;
            diff += mod;
            div -= mod;
        }
        result.push(div);
    });
    resultSum = result.reduce(function(a, b){ return a + b; }, 0);
    if (resultSum < sum) {
        result.push(sum - resultSum);
    }
    return result;
}


Update (fix rounding)

function divideMoney(sum, percentages, denomination) {
    var result = [], remainder = sum, part, i;
    for(i = 0; i < percentages.length - 1; i++) {
        part = percentages[i] * sum;
        if (part % 1) {
            part = Math.round(part/denomination)*denomination;
        }
        remainder -= part; 
        result.push(part);
    }
    result.push(remainder);
    return result;
}

Solution

I can make infinite money (well, as much as will fit in a javascript number) with your code!

var money = 10;
while(true){
    money = divideMoney(money, [3, 0], 1)[0];//muhahahahah infinite money
}


Which divides the money like so: 1 for me, 1 for myself, 1 for I, none for you. 1 for me...

I'd recommend in this case to fall back on relative percentages: that is, sum the percentages and then set the cut to be the percentage of the summed percentage. So 10, 5, 5 = 20 total, 10/20 = 0.5, 5/20 = 0.25, so it's 0.50, 0.25, 0.25.

Code Snippets

var money = 10;
while(true){
    money = divideMoney(money, [3, 0], 1)[0];//muhahahahah infinite money
}

Context

StackExchange Code Review Q#121775, answer score: 2

Revisions (0)

No revisions yet.