It's not passing the last test

Tell us what’s happening:
I don’t know why the every value of cid becomes 0 after the i becomes zero. Is it that when I execute arr[i] with i being negative then every array
Your code so far


const currArr=[0.01,0.05,0.1,0.25,1,5,10,20,100]
function checkCashRegister(price, cash, cid) {
 let drawer=[...cid];
 let change=(cash-price).toFixed(2);
 const display=[];
 // Here is your change, ma'am.

let i=8
while(change!=0 &&change>0){
  //the loop below returns the highest currency in ehich we can give change 
 while((change/currArr[i])<1){
   i--;
 }

 let changeToBePaid=Math.floor(change/currArr[i])*currArr[i]
 if(changeToBePaid>drawer[i][1])changeToBePaid=drawer[i][1];
 display.push([drawer[i][0],changeToBePaid])
 change-=changeToBePaid;
 drawer[i][1]-=changeToBePaid
 change=change.toFixed(2);
 i--;
 if(i<0 &&change>0){
   return {status: "INSUFFICIENT_FUNDS", change: []};
 }
 }
 if(totalCashInDrawer(drawer)==0){return {status:"CLOSED",change:cid}}
 return {status:"OPEN",change:display};
}

//counts cash in drawer after giving the change
function totalCashInDrawer(drawer){
 let result=0;
 for(let i=0;i<drawer.length;i++)result+=drawer[i][1];
 return result;
}
// Example cash-in-drawer array:
// [["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]]))
//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]]);

Your browser information:

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

Challenge: Cash Register

Link to the challenge:

The problem lies here: let drawer=[...cid];
... produces only a “true” copy of the array, if it is a 1D array of primitives
You can look up the difference between “shallow copy” and “deep copy”.

See in the logging below, that cid changes after you manipulate on drawer

I hope this was helpful to you :slight_smile:

One additional question:
Are you aware (and just too lazy, because it works :wink:) that you are implicitly converting string to num (and vice versa) at a lot of places?

I added a bit more logging to your code:

const currArr=[0.01,0.05,0.1,0.25,1,5,10,20,100]
function checkCashRegister(price, cash, cid) {
 console.log(`original cid: ${cid}`)
 
 let drawer=[...cid];
 let change=(cash-price).toFixed(2);
 const display=[];
 // Here is your change, ma'am.

let i=8
while(change!=0 &&change>0){
  //the loop below returns the highest currency in ehich we can give change 
 while((change/currArr[i])<1){
   i--;
 }
 
 console.log(`${i} ${change} ${currArr[i]} ${change/currArr[i]} --- drawer: ${drawer[i][0]} ${drawer[i][1]}`)
 console.log(cid)

 let changeToBePaid=Math.floor(change/currArr[i])*currArr[i]
 if(changeToBePaid>drawer[i][1])changeToBePaid=drawer[i][1];
 if (changeToBePaid > 0) { // would check if changeToBePaid > 0
    display.push([drawer[i][0],changeToBePaid]);
    change-=changeToBePaid;
    drawer[i][1]-=changeToBePaid
    change=change.toFixed(2);
    console.log(`manipulation on drawer -> cid: ${cid}`)
 } 
 i--;
 if(i<0 &&change>0){
   return {status: "INSUFFICIENT_FUNDS", change: []};
 }
 }
 if(totalCashInDrawer(drawer)==0){return {status:"CLOSED",change:cid}}
 return {status:"OPEN",change:display};
}

//counts cash in drawer after giving the change
function totalCashInDrawer(drawer){
 let result=0;
 for(let i=0;i<drawer.length;i++)result+=drawer[i][1];
 return result;
}
// Example cash-in-drawer array:
// [["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]]))
//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]]);

And this is the result (interesting part at the bottom after i=0):

original cid: PENNY,0.5,NICKEL,0,DIME,0,QUARTER,0,ONE,0,FIVE,0,TEN,0,TWENTY,0,ONE HUNDRED,0
3 0.50 0.25 2 --- drawer: QUARTER 0
[ [ 'PENNY', 0.5 ],
  [ 'NICKEL', 0 ],
  [ 'DIME', 0 ],
  [ 'QUARTER', 0 ],
  [ 'ONE', 0 ],
  [ 'FIVE', 0 ],
  [ 'TEN', 0 ],
  [ 'TWENTY', 0 ],
  [ 'ONE HUNDRED', 0 ] ]
2 0.50 0.1 5 --- drawer: DIME 0
[ [ 'PENNY', 0.5 ],
  [ 'NICKEL', 0 ],
  [ 'DIME', 0 ],
  [ 'QUARTER', 0 ],
  [ 'ONE', 0 ],
  [ 'FIVE', 0 ],
  [ 'TEN', 0 ],
  [ 'TWENTY', 0 ],
  [ 'ONE HUNDRED', 0 ] ]
1 0.50 0.05 10 --- drawer: NICKEL 0
[ [ 'PENNY', 0.5 ],
  [ 'NICKEL', 0 ],
  [ 'DIME', 0 ],
  [ 'QUARTER', 0 ],
  [ 'ONE', 0 ],
  [ 'FIVE', 0 ],
  [ 'TEN', 0 ],
  [ 'TWENTY', 0 ],
  [ 'ONE HUNDRED', 0 ] ]
0 0.50 0.01 50 --- drawer: PENNY 0.5
[ [ 'PENNY', 0.5 ],
  [ 'NICKEL', 0 ],
  [ 'DIME', 0 ],
  [ 'QUARTER', 0 ],
  [ 'ONE', 0 ],
  [ 'FIVE', 0 ],
  [ 'TEN', 0 ],
  [ 'TWENTY', 0 ],
  [ 'ONE HUNDRED', 0 ] ]
manipulation on drawer -> cid: PENNY,0,NICKEL,0,DIME,0,QUARTER,0,ONE,0,FIVE,0,TEN,0,TWENTY,0,ONE HUNDRED,0
{ status: 'CLOSED',
  change: 
   [ [ 'PENNY', 0 ],
     [ 'NICKEL', 0 ],
     [ 'DIME', 0 ],
     [ 'QUARTER', 0 ],
     [ 'ONE', 0 ],
     [ 'FIVE', 0 ],
     [ 'TEN', 0 ],
     [ 'TWENTY', 0 ],
     [ 'ONE HUNDRED', 0 ] ] }
1 Like

Just to add to that, you don’t need to copy here. If you think about this in real-life terms, a cash register doesn’t clone it’s contents before giving change; if it did it would always have the same amount of cash it started with regardless of how many transactions were made. You actually want to change the amount in the drawer.

1 Like

Oh! I didn’t know that [...arr] just shallow copies 1D arrays. Very Useful information.

Yes I do know that toFixed() returns a string.

Here’s what you meant probably.

const Arr1=[[1,2],[2,3]]
const Arr2=[...Arr1]

const arr1=[1,2,3];
const arr2=[...arr1];

Arr2[0][1]=3;
console.log(Arr1)//manipulated array

arr2[0]=3
console.log(arr1)//non manipulated array

Exactly :slight_smile:

@DanCouper is right, that a copy of the drawer is not necessary and a solution without it would be maybe preferred.

But with 1-3 lines of additional code (depending on formatting) you can save your solution and bring it to pass the test - and just keep it in mind for the next solutions :wink:

You could loop through the array and make only shallow copies of the arrays within (with two elements).