JavaScript Algorithms and Data Structures Projects - Cash Register

Hi! I´m having some troubles with this challenge. I´ve been able to pass all test except one:

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]]}

but mine is returning:

{ status: 'OPEN',
  change: 
   [ [ 'TWENTY', 40 ],
     [ 'TEN', 20 ],
     [ 'FIVE', 5 ],
     [ 'ONE', 1 ],
     [ 'QUARTER', 0.5 ] ] }

I´ve tried to console.log everything, but still don´t know how to solve it.
Thanks in advance!

Your code so far

function checkCashRegister(price, cash, cid) {
  let cashInDrawer = cid;
  let cashInDrawerReverse = cashInDrawer.reverse();
  let currencyUnits = [
     ["ONE HUNDRED", 100],
     ["TWENTY", 20],
     ["TEN", 10],
     ["FIVE", 5],
     ["ONE", 1],
     ["QUARTER", 0.25],
     ["DIME", 0.1],
     ["NICKEL", 0.05],
     ["PENNY", 0.01]
  ];

  let availableMoney = [];
  let totalAvailableMoney = 0;
  let totalChange = cash - price;
  let change = []
  
  //Check the available money:
  for(let index = 0; index < cid.length; index++){
    availableMoney.push(cid[index][1]);
  }

  availableMoney.reverse();

  //Total of available money:
  
  for(let f = 0; f < availableMoney.length; f++){
    totalAvailableMoney += availableMoney[f];
  }

  //Returns:

  if(totalChange > totalAvailableMoney){
    return {status: "INSUFFICIENT_FUNDS", change: []}
  }
  else if (totalChange === totalAvailableMoney){
    return {status: "OPEN", change: cashInDrawer.reverse()}
  } 
  else {
    for(var i = 0; i < cashInDrawerReverse.length; i++){
     if(cashInDrawerReverse[i][1] != 0){
      while(totalChange >= currencyUnits[i][1]){
        //Check if that currency unit is already present in the change array
        let changeLength = change.length;
      if(cashInDrawerReverse[i][1] > 0){
        if(change[changeLength-1] == currencyUnits[i]){
          change[changeLength-1][1] += currencyUnits[i][1]
        } else{
          change.push(currencyUnits[i]);
        }
          cashInDrawer[i][1] -= currencyUnits[i][1];
          totalChange -=  currencyUnits[i][1]
        } else {
          return {status: "INSUFFICIENT_FUNDS", change: []} 
        }
      }
     }
    }
    
    return {status: "OPEN", change: change}
  }

}

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", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]))

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36

Challenge: JavaScript Algorithms and Data Structures Projects - Cash Register

Link to the challenge:

I can see two tests failing.

First case has [ ‘TWENTY’, 40 ] should have 60 in “TWENTY” instead? - has more to it

The second case (the very last one) is because of the status:

Expects status: “CLOSED” while your solution has status: “OPEN”

1 Like

Yes! I realized what was wrong with the second one rigth after posting this hahah thanks! I still couldn´t figure out the first one though.
I know my code is failing somewhere, because if you sum the change mine is returning, is less than the change it should be returning. but the totalChange variable is correct

[IGNORE me] Not sure about first case.

Such an annoying challenge.

1 Like

Totally agree :grimacing: It´s driving me insane haha

I’d break down the logic in separate functions.
Best way to see what is wrong.
On a quick look I cannot figure it out what is wrong.

i suggest you post your most recent code if the above is already out-of-date

1 Like
function checkCashRegister(price, cash, cid) {
  let cashInDrawer = cid;
  let cashInDrawerReverse = cashInDrawer.reverse();
  let currencyUnits = [
     ["ONE HUNDRED", 100],
     ["TWENTY", 20],
     ["TEN", 10],
     ["FIVE", 5],
     ["ONE", 1],
     ["QUARTER", 0.25],
     ["DIME", 0.1],
     ["NICKEL", 0.05],
     ["PENNY", 0.01]
  ];

  let availableMoney = [];
  let totalAvailableMoney = 0;
  let totalChange = cash - price;
  let change = []
  
  //Check the available money:
  for(let index = 0; index < cid.length; index++){
    availableMoney.push(cid[index][1]);
  }

  availableMoney.reverse();

  //Total of available money:
  
  for(let f = 0; f < availableMoney.length; f++){
    totalAvailableMoney += availableMoney[f];
  }

  //Returns:

  if(totalChange > totalAvailableMoney){
    return {status: "INSUFFICIENT_FUNDS", change: []}
  }
  else if (totalChange === totalAvailableMoney){
    return {status: "CLOSED", change: cashInDrawer.reverse()}
  } 
  else {
    for(var i = 0; i < cashInDrawerReverse.length; i++){
     if(cashInDrawerReverse[i][1] != 0){
      while(totalChange >= currencyUnits[i][1]){
        /*Check if that currency unit is already present in the change array, here is where i´m having some troubles*/
        let changeLength = change.length;
      if(cashInDrawerReverse[i][1] > 0){
        if(change[changeLength-1] == currencyUnits[i]){
          change[changeLength-1][1] += currencyUnits[i][1]
        } else{
          change.push(currencyUnits[i]);
        }
          cashInDrawer[i][1] -= currencyUnits[i][1];
          totalChange -=  currencyUnits[i][1]
        } else {
          return {status: "INSUFFICIENT_FUNDS", change: []} 
        }
      }
     }
    }
    
    return {status: "OPEN", change: change}
  }

}

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]]))

the logic here is really hard to understand.
Can you add more comments or explain the algorithm?

For eg. It makes sense that you want to figure out how many of each currency you can break the required return amount into, but if you had to do this yourself - say you were standing at an actual cash register, what would you be doing (perhaps using some mental maths?) to get the required change amounts?

1 Like

Ohh, I will try adding some comments there to make it more easy to understand, sorry! I usually break down the logic on a piece of paper, but forgot to wrote that in the code itself as a comment :sweat_smile:

 for(var i = 0; i < cashInDrawerReverse.length; i++){
     if(cashInDrawerReverse[i][1] != 0){
      while(totalChange >= currencyUnits[i][1]){ 
      if(cashInDrawerReverse[i][1] > 0){
        let changeLength = change.length;
        //Check if that currency unit is already present in the change array. I´m pretty sure the problem is here, I thought of doing if(change[changeLength-1][0] == currencyUnits[i][0]), but that way the code doesn´t run
        if(change[changeLength-1] == currencyUnits[i])
        {
          //If it is, sum the currency amount
          change[changeLength-1][1] += currencyUnits[i][1]
        }
        //if it isnt, add the new currency unit
        else{
          change.push(currencyUnits[i]);
        }
        //"actualize" the amount that we still have in the cash register
          cashInDrawer[i][1] -= currencyUnits[i][1];
          //rest te amount we´ve just add in the change variable to the totalChange, so that we know how much change we still need to give
          totalChange -=  currencyUnits[i][1];
        } else {
          //
          return {status: "INSUFFICIENT_FUNDS", change: []} 
        }
      } 
     }

Do this comments make it more clear?

tbh no. For eg. why do you loop over the cashInDrawerReverse but later on modify the cashInDrawer amounts?
I’m not clear what is the overall method here is.

If I’m doing this as an actual cashier, it would make sense that I would ‘loop’ through the amounts in my cash register starting with the largest amount, but it doesn’t make sense that I have two cash registers that I’m referring to at the same time to figure out how much change to give.

So that’s why I suggest working out what is the actual algorithm here.

  • loop through the cash register starting from the largest currency down
  • then check if amount owed is less than the current currency
  • if it is less then…???

(In real life, how would you determine that you need to take out 3 20s to give the change for the current amount owed?)

1 Like

Ohh, I get what you mean about looping over cashInDrawerReverse and then modifying the cashInDrawer. That was a silly mistake I made :sweat_smile: but since one is a reference of the other, that didn´t had an impact on my code performace. However, thank you for pointing it out, I have fixed it and will be more careful with that in the future.
About the algorithm what I though was:

  1. If the amount i owe is less than the actual currency, I need to loop over the amounts in my cash register.
  2. Check if the amount I owed is bigger that my current currency. (In this case, I owe around $96, and my current currencyUnit(in the first iteration) is $100, so I pass to the next iteration )
  3. if the mount I owed is bigger that my current currency, I need to check if I have that currency in my drawer /I think here is where my logic is having some problems/
  4. if not, return “INSUFFICIENT_FUNDS”, since I wont be able to give exact change.
  5. If i do have that currency in my drawer, I´ll check if my array already contains that currency unit (I know I should be thinking in a real life situation, but I cannot repeat currency units in my array, or else it wont pass the test). If it does i just simply sum that currency amount in my arr, and if not i add that currency unit in my array.
  6. Then i just actualize the amount in my cash in drawer and the amount i owe, and continue with the loop until I have gone through al the currency units.

I know my logic has some weak points, but I haven´t been able to fix them in my code

What if you forgot about the code for a bit?

Can you finish this the way you would do it as a person?
(The loop is what you would do as a person because you would need to check through the cash step by step to see what works but what happens later when the change is greater than the $20 currency for eg?)

For me I would do some mental math. I don’t want to tell you specifically how because this should be yours.

If you can work out how you would do this as a person then the code will be just an implementation of that.

The way you started here for me is not something anyone would do? You wouldn’t loop twice? You would just check your cash drawer right? Because it doesn’t matter if the amount owed is greater than 100 if you don’t have any hundred dollar bills?

I hope you see why I am urging you to work out a solid algorithm first?

Ps. If the amount owed was 600 would you really sit there and subtract one twenty dollar bill at a time or would you ____(fill in the blank to find how many bills you need?
I am not saying you can’t do it that way if you really want to, just that maybe you already know a better way?

1 Like

Ohh, I totally get what you mean. Thanks!

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.