I would like to limit the amount of something making up the whole to a certain percentage. Probably it's best explained by an example:
A: $45.00 (45% of $100)
B: $35.00 (35% of $100)
C: $10.00 (10% of $100)
D: $10.00 (10% of $100)
----------
$100.00
The rule I have to adhere is, that the biggest item can't be bigger than 40% and the others not more than 30% of the whole. Amounts cannot be increased, only decreased. So I get this:
A: min($45.00, $100.00 * 0.4) = $40.00 (44.4% of $90)
B: min($35.00, $100.00 * 0.3) = $30.00 (33.3% of $90)
C: min($10.00, $100.00 * 0.3) = $10.00 (11.1% of $90)
D: min($10.00, $100.00 * 0.3) = $10.00 (11.1% of $90)
----------
$90.00
This reducing the amounts also reduced the sum, which is want I want, but $40.00 is obviously more than 40% of $90.00. So I must do it again:
A: min($40.00, $90.00 * 0.4) = $36.00 (43.3% of $83)
B: min($30.00, $90.00 * 0.3) = $27.00 (32.5% of $83)
C: min($10.00, $90.00 * 0.3) = $10.00 (12% of $83)
D: min($10.00, $90.00 * 0.3) = $10.00 (12% of $83)
----------
$83.00
But again, the A now represents about 43% of the total, and B 32%, higher than the limits I want to adhere.
For these small numbers, it takes 20 rounds to come to this result, which is final thanks to the fact that I can't have parts of cents and I always round down:
A: $26.66 (40% of $66.65)
B: $19.99 (29.9% of $66.65)
C: $10.00 (15% of $66.65)
D: $10.00 (15% of $66.65)
---------
$66.65
Isn't there a way to calculate this more efficiently? I have to often calculate with way higher amounts, so I expect more iterations.
If it's useful to anyone, we found a solution: Take the amount of the values that are fine (
C&D). If forA40% is allowed and forB30%, then this must make up (100% - 40% - 30% = 30%). From there, we can calculate the total andA&B: