Cash Register currency adding issue

I am currently working the Cash Register project in the javascript course here on freecodecamp. I have tried several different solutions, but I can’t get the last part right.

The function will return an object with the currency that you are supposed to receive back from the cash register, but it is individually separated from each other. For example, where you are supposed to get two quarters back, it should be QUARTER: 50, not two QUARTER: 25.

Therefore I made a for loop with an if function right before returning the change. It is supposed to look forward and check if it has the same name as the current, and then add the sums into one array and delete the other. I think there might be a problem with deleting them since the i in the for loop is not correct.

Is there any smart solution to this? I know that I could solve the whole project in a different way, but I did not understand the other methods that I have seen.

function checkCashRegister(price, cash, cid) {
  
  let changeTotal = cash - price; //Total amount of change
  let change = []; //Array with currency change

  let cidTotal = 0;
  for (let i in cid) {cidTotal += cid[i][1];} //Total amount in cash-drawer
  cidTotal = Math.round(cidTotal*100)/100; //Round number to two decimals

  //Check if sufficient funds or closed before calculating change
  if (cidTotal < changeTotal) {return {status: "INSUFFICIENT_FUNDS", change: []} }
  else if (cidTotal === changeTotal) {change = cid; return {status: "CLOSED", change} }

  let currency = [100, 20, 10, 5, 1, 0.25, 0.1, 0.05, 0.01]; //Actual value
  cid.reverse(); //Reverse to get highest currency first

  for (let i in cid) {
    while (changeTotal >= currency[i] && cid[i][1] > 0) {
       change.push([cid[i][0], currency[i]]);
       changeTotal -= currency[i];
       cid[i][1] -= currency[i];
    }
  }
  
//Fix for the change array / the issue of this topic
  for (let i = 0; i < change.length -1; i++) {
    if (change[i][0] === change[i+1][0]) {
      change[i][1] += change[i+1][1];
      change.splice(i+1, 1)
    }
  }
  return  {status: "OPEN", change};
}

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

How about doing something like this?

for (let i in cid) {

    let denominationTotal = 0; // accumulator

    while (changeTotal >= currency[i] && cid[i][1] > 0) {
       //change.push([cid[i][0], currency[i]]);
       changeTotal -= currency[i];
       cid[i][1] -= currency[i];
       denominationTotal += currency[i]
    }

    // if accumulator not 0, push onto change
    if(denominationTotal){ 
       change.push([cid[i][0], denominationTotal]);
    }
  }

That is a great solution, thank you!

Though it seems to be working with most of the challenges, two of them is not passed.

This:
checkCashRegister(19.5, 20, [["PENNY", 0.01], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 1], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])

Should return this:
{status: "INSUFFICIENT_FUNDS", change: []}.

But returns this:

{ status: 'OPEN', change: [ [ 'PENNY', 0.01 ] ] }

This must be because of the if statement on line 12 is only run if the cidTotal amount is lower than the changeTotal amount, but should only return if the change currency is not available.

Also with:


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

It is missing a penny, I figured it must have been the Math.round(cidTotal), but I checked and the math checks out, so I am not sure what is causing this issue.

Have you solved this, yet?

In case you haven’t or this will be helpful to anyone else:

This issue might be caused by this line:

if (cidTotal < changeTotal) {return {status: "INSUFFICIENT_FUNDS", change: []} }

Right now, if the total cid is less than the changeTotal, you’ll return:

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

But if you have a circumstance where your total cid is more than the changeTotal, but you don’t have enough of a certain currency to give exact change, you’ll end up with the wrong result.
e.g. if you only have a $100 bill in the cid, the price is $4.99, and the cash is $5, you have more than enough change, but the currency isn’t precise enough.

Does that make sense? If not, I can try to clarify further.