Hi there, I could really use some help on the cash register. I’ve been stuck for hours, and I feel like I’m close to figuring it out, but I can’t seem to wrap my finger around the issue.
The problem has to do with float calculations, they’re inaccurate and I think they’re giving me a rounding error especially on the pennies. I seem to be off on 0.01 on the following tests:
checkCashRegister(3.26, 100, [[“PENNY”, 1.01], [“NICKEL”, 2.05], [“DIME”, 3.1], [“QUARTER”, 4.25], [“ONE”, 90], [“FIVE”, 55], [“TEN”, 20], [“TWENTY”, 60], [“ONE HUNDRED”, 100]]) should return {status: “OPEN”, change: [[“TWENTY”, 60], [“TEN”, 20], [“FIVE”, 15], [“ONE”, 1], [“QUARTER”, 0.5], [“DIME”, 0.2], [“PENNY”, 0.04]]}.
When I check my calculations, penny turns out to be 0.03.
checkCashRegister(19.5, 20, [[“PENNY”, 0.5], [“NICKEL”, 0], [“DIME”, 0], [“QUARTER”, 0], [“ONE”, 0], [“FIVE”, 0], [“TEN”, 0], [“TWENTY”, 0], [“ONE HUNDRED”, 0]]) should return {status: “CLOSED”, change: [[“PENNY”, 0.5], [“NICKEL”, 0], [“DIME”, 0], [“QUARTER”, 0], [“ONE”, 0], [“FIVE”, 0], [“TEN”, 0], [“TWENTY”, 0], [“ONE HUNDRED”, 0]]}.
Here, my penny ends up with 0.49.
Here’s my code so far:
const REGOBJ = {
'ONE HUNDRED': 100.00,
'TWENTY': 20.00,
'TEN': 10.00,
'FIVE': 5.00,
'ONE': 1.00,
'QUARTER': 0.25,
'DIME': 0.10,
'NICKEL': 0.05,
'PENNY': 0.01
};
function checkCashRegister(price, cash, cid) {
let change = cash - price;
// calculate total cash in drawer
let cidTotal = 0;
for (let i = 0; i<cid.length; i++) {
cidTotal += cid[i][1];
}
const cidCopy = cid.slice();
// make sure to only round at 2 decimals
cidTotal = Math.round(cidTotal * 100) / 100;
// if total cash in drawer is less then change, return.
if (change > cidTotal) {
return {status: "INSUFFICIENT_FUNDS", change: []}
}
// create arr to push change on
let changeArr = [];
// loop over cid backwards, so we start with the highest amount.
for(let j = cid.length - 1; j >= 0; j--){
// reduce change with current money in cid
let nameOfValue = cid[j][0];
let valueAmount = 0;
while (change > 0 && cid[j][1] > 0) {
if ( change < 0 || cid[j][1] < 0) {
break;
} else if ((change - REGOBJ[nameOfValue]) < 0) {
break;
}
change -= REGOBJ[nameOfValue];
cid[j][1] -= REGOBJ[nameOfValue];
valueAmount += REGOBJ[nameOfValue];
cidTotal -= REGOBJ[nameOfValue];
} // end of while loop
if (valueAmount > 0) {
valueAmount = Math.round(valueAmount * 100) / 100;
changeArr.push(nameOfValue, valueAmount);
}
} // end of for loop
console.log(changeArr);
// if change is still over 0 after the loop we dont have exact change
if (change > 0) {
return {status: "INSUFFICIENT_FUNDS", change: []};
// if total equals 0, we have exact change
} else if (cidTotal === 0) {
return {status: "CLOSED", change: [cidCopy]}
} else {
return{status: "OPEN", change: [changeArr]};
}
}
checkCashRegister(19.5, 20, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]);