patternjavascriptMinor
Function that divides money with regard to the smallest denomination
Viewed 0 times
regardmoneysmallestthewithfunctiondividesthatdenomination
Problem
I'm writing a function
For example:
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 (
Here is what I tried
Original Code
Update (fix rounding)
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!
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.
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.