diff --git a/lib/bill-math.js b/lib/bill-math.js index 2e1542e3..b665840a 100644 --- a/lib/bill-math.js +++ b/lib/bill-math.js @@ -16,6 +16,38 @@ exports.makeChange = function makeChange (cassettes, amount) { // it still requires a fallback for cases where it might not provide any solution. // Example: Denominations: [3, 5, 10] | User inputs 4 times the [3] button, resulting in a 12 fiat tx // This algorithm resolves for 1 x [10], and can't resolve the remainder of 2 + + return _.length(cassettes) > 2 ? makeChangeDynamic(cassettes, amount) : makeChangeDuo(cassettes, amount) +} + +function makeChangeDuo (cassettes, amount) { + const small = cassettes[0] + const large = cassettes[1] + + const largeDenom = large.denomination + const smallDenom = small.denomination + const largeBills = Math.min(large.count, Math.floor(amount / largeDenom)) + + const amountNum = amount.toNumber() + + for (let i = largeBills; i >= 0; i--) { + const remainder = amountNum - largeDenom * i + + if (remainder % smallDenom !== 0) continue + + const smallCount = remainder / smallDenom + if (smallCount > small.count) continue + + return [ + {provisioned: smallCount, denomination: small.denomination, id: uuid.v4()}, + {provisioned: i, denomination: largeDenom, id: uuid.v4()} + ] + } + + return null +} + +function makeChangeDynamic (cassettes, amount) { const cassetteMap = _.map(cassettes, it => ({ denomination: it.denomination }))