Cash register project help needed -very lost

This seems to be returning the correct change on the second test, but not the first. I can’t figure out what is wrong with my code.

Update: I added some console logs and I think I found the problem. When finding the highestUnit it includes 20 four times and when I check

if (cid[unitIndex][1] >= highestUnit)

It skips the 4th 20 and leaves me with an incorrect change from that point. How can I fix this?

function checkCashRegister(price, cash, cid) {

  let cashValues =[.01, .05, .1, .25, 1, 5, 10, 20, 100];

  var index = 0;

  var totalCash = 0;

  var changeDue = 0;

  var returnChange = [];

  

  for (var i = 0; i < cid.length; i++) {

    totalCash += cid[i][1];

  }totalCash = totalCash.toFixed(2);

changeDue = cash - price;

if (changeDue > totalCash) {

  return {status: "INSUFFICIENT_FUNDS", change: []}

}

if (changeDue == totalCash) {

    return {status: "CLOSED", change: cid}

}

      while (changeDue > 0) {

var highestUnit = Math.max.apply(Math, cashValues.filter(function(x){return x <= changeDue}

));

var unitIndex = cashValues.indexOf(highestUnit)

 

  if (cid[unitIndex][1] >= highestUnit) {

returnChange.push([cid[unitIndex][0], highestUnit ]);

cid[unitIndex][1]=cid[unitIndex][1] - highestUnit;

  }

  changeDue = (changeDue - highestUnit).toFixed(2);

}

console.log(returnChange)

console.log(cid)

}

console.log(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]]));

console.log(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]]));

I can’t debug, but you may have found yourself with floating point math errors

the same that make so that this is false: 0.1 + 0.2 === 0.3
why false? because it results in 0.30000000000000004 (or something like, I’m unsure on the number of zeros)

if you print the number to the console, what number do you get?

to solve that you could do what financial institutions do, count pennies: so instead of having the value of "TEN" as 10 you have it as 1000, just multiplying everything by 100

but remember you want the final result in dollars, so you need to make the opposite thing before returning

Do you think that approach would be the easiest way to solve this problem? I’ve finished all the other projects, but I can’t seem to crack this one.

the floating point error will always happen, bringing everything to whole numbers is the simplest way to avoiding it - it’s what financial instructions do to avoid having money appear and disappear

Just to make sure I understand before moving forward.
Is this correct?

((100 * 100) - (3.26 * 100)) / 100

no, just work with pennies for the whole algorithm, and then return to dollars only to return a value

Okay, I’m gonna give that a shot. Thank you!

Now I had chance to debug your code

Issues:

returnChange.push([cid[unitIndex][0], highestUnit ]);

this will push the 20 each time, as you don’t count how many times you need to give back a 20, just each time you need to give back a 20, you add a 20 to the change array

same for your pennies actually

if you have diffculties seeing your code-flow, use this tool: http://pythontutor.com/javascript.html

You will notice that at one point you stop having numbers, and start having strings. It works, because JavaScript, but it’s not really nice to do. That’s because toFixed returns a string

So I would still need to find a way to fix this even working with pennies, right?

yes

but I started with floating point error because it’s something that can cause issues when adding decimal numbers

Thanks for the link, I’m gonna use that and see if I can find a way to fix this.

I can’t figure out a way to to count how many times I can give back a 20.

maybe a loop that until the currently checked denomination is lower than the change due both substract from the change due and add to a temporary variable that hold the value to give with current denomination?

while (changeDue > 0) {

var highestUnit = Math.max.apply(Math, cashValues.filter(function(x){return x <= changeDue}

));

if (newArr[cashValues.indexOf(highestUnit)] >= highestUnit)

newArr[cashValues.indexOf(highestUnit)] = newArr[cashValues.indexOf(highestUnit)] - highestUnit;

changeDue = changeDue - highestUnit

returnChange.push(highestUnit)

      }

I’m still stuck here and it seems I pretty much did what I did last time with the same outcome.

I got it to work. Just need to figure out how to convert

[ [ ‘TWENTY’, 2000 ],
[ ‘TWENTY’, 2000 ],
[ ‘TWENTY’, 2000 ],
[ ‘TEN’, 1000 ],
[ ‘TEN’, 1000 ],
[ ‘FIVE’, 500 ],
[ ‘FIVE’, 500 ],
[ ‘FIVE’, 500 ],
[ ‘ONE’, 100 ],
[ ‘QUARTER’, 25 ],
[ ‘QUARTER’, 25 ],
[ ‘DIME’, 10 ],
[ ‘DIME’, 10 ],
[ ‘PENNY’, 1 ],
[ ‘PENNY’, 1 ],
[ ‘PENNY’, 1 ],
[ ‘PENNY’, 1 ] ]

it seems you still have the same issue

I’m suppose to return $15 in 5s though

you need to have ['FIVE', 15] if in dollars or ['FIVE', 1500] if in pennies

Yes, so I need to figure out how to change this to [‘FIVE’, 1500] instead of three separate arrays.

Before I was getting
[ [ ‘TWENTY’, 2000 ],
[ ‘TWENTY’, 2000 ],
[ ‘TWENTY’, 2000 ],
[ ‘TEN’, 1000 ],
[ ‘FIVE’, 500 ],
[ ‘ONE’, 100 ],
[ ‘QUARTER’, 25 ],
[ ‘QUARTER’, 25 ],
[ ‘DIME’, 10 ],
[ ‘DIME’, 10 ],
[ ‘PENNY’, 1 ],
[ ‘PENNY’, 1 ],
[ ‘PENNY’, 1 ],
[ ‘PENNY’, 1 ] ]

maybe it’s easier if you change a bit approach:

a loop over the denominations array, from the biggest one to the lowest one
if the total change due is biggest than the denomination, you can decrease the total change due and at the same time incease a temporary variable - only once the due change becomes lower than the current denomination you add that value to the change array, and then change denomination