Cash Register Help (Recursion)

Hello,

I’m having trouble advancing to the next value of money in my while loop.

Hopefully my notes will make the specific area clear.

I’m wondering if I just can’t do what I am trying to do because of scope or if I’m just overlooking something.

datMon should ideally recursively change to an updated value once the amount of the larger value of currency has been depleted.

Thanks!

function checkCashRegister(price, cash, cid) {

  // =============================================================================
  // ()()()()()()()()()()()()([ VALUES OF TENDER ]()()()()()()()()()()()()()()()()
  // =============================================================================

let monies = [
  {name: "ONE HUNDRED", value: 100.00},
  {name: "TWENTY", value: 20.00},
  {name: "TEN", value: 10.00},
  {name: "FIVE", value: 5.00},
  {name: "ONE", value: 1.00},
  {name: "QUARTER", value: 0.25},
  {name: "DIME", value: 0.10},
  {name: "NICKEL", value: 0.05},
  {name: "PENNY", value: 0.01},
];

  // =============================================================================
  // ()()()()()()()()()()()()([ TOTALS OF TENDER ]()()()()()()()()()()()()()()()()
  // =============================================================================

  let totalPennies = (cid[0][1] / monies[8].value);
  
  let unroundedNickels = (cid[1][1] / monies[7].value);

  let totalNickels = Number((unroundedNickels).toFixed(2));
  
  let totalDimes = (cid[2][1] / monies[6].value);
  
  let totalQuarters = (cid[3][1] / monies[5].value);
  
  let totalOnes = (cid[4][1] / monies[4].value);

  let totalFives = (cid[5][1] / monies[3].value);

  let totalTens = (cid[6][1] / monies[2].value);

  let totalTwenties = (cid[7][1] / monies[1].value);

  let totalHundreds = (cid[8][1] / monies[0].value);

  let totalsOf = [
    {name: "HUNDREDS", amount: totalHundreds},
    {name: 'TWENTIES', amount: totalTwenties},
    {name: 'TENS', amount: totalTens},
    {name: 'FIVES', amount: totalFives},
    {name: 'ONES', amount: totalOnes},
    {name: 'QUARTERS', amount: totalQuarters},
    {name: 'DIMES', amount: totalDimes},
    {name: 'NICKLES', amount: totalNickels},
    {name: 'PENNIES', amount: totalPennies}
  ];

  // =============================================================================
  // ()()()()()()()()()()()()()()[ SET VARIABLES ]()()()()()()()()()()()()()()()()
  // =============================================================================

  // SET UP CHANGE VARIABLE
  let change = cash - price;

  // SET UP RESULT OBJECT
  let Result = {status: "", change: []};

  // ADD VALUES IN DRAWER
  let cidTotal = (cid[0][1] + cid[1][1] + cid[2][1] + cid[3][1] + cid[4][1] + cid[5][1] +    cid[6][1] + cid[7][1] + cid[8][1]);

  // LET THAT TOTAL EQUAL THE TRUE USED TOTAL
  let trueTotal = Number((cidTotal).toFixed(2));

  // REVERSE THE CID TO WORK BETTER IN LOOPS
  let usefulCID = cid.reverse();

  // ===============================================================================
  // ()()()()()()()()()()()()()()[ SET UP REGISTER ]()()()()()()()()()()()()()()()()
  // ===============================================================================

  // REGISTER OBJECT
  // HOW WE REFERENCE OUR VARIOUS VARIABLES
  let Register = {total: trueTotal, amountsOf: totalsOf, tenders: usefulCID, money: monies};

  // ===============================================================================
  // ()()()()()()()()()()()()()()[ IF CHECKS ]()()()()()()()()()()()()()()()()()()()
  // ===============================================================================

  // CHECK IF THE AMOUNT NEEDED FOR CHANGE IS GREATER THAN THE TOTAL IN DRAWER
  if (trueTotal < change) {
    Result.status = "INSUFFICIENT_FUNDS";
    Result.change = [];
    return Result;
  };

  // CHECK IF THE AMOUNT IN THE DRAWER IS EQUAL TO THE CHANGE NEEDED
  if (trueTotal == change) {
    Result.status = "CLOSED";
    Result.change = cid;
    return Result;
  };

  // CHECK IF THE AMOUNT IN DRAWER IS ENOUGH TO GIVE THE CUSTOMER THEIR CHANGE
  if (trueTotal > change) {

    // LOOP THROUGH THE AMOUNTS OF TENDER
    // SINCE WE KNOW WE HAVE ENOUGH TO GIVE CHANGE
    for (let i = 0; i < Register.amountsOf.length; i++ ) {

      // SET UP VARS
      let updatedChange = 0;
      let fixedChange = 0;
      let objArr = [];
      let num = 0;
      let updatedAmt = 0;
      let amt = 0;
      let datMon = 0;

        // ESTABLISH HOW MUCH THE CHANGE IS
        // AND GIVE THEM AMOUNTS OF TENDER LESS THAN THE AMOUNT
        if (change >= Register.money[i].value && Register.amountsOf[i].amount > 0) {

          datMon = Register.money[i].value
          console.log("DAT MON: " + datMon)

          // SOME CONSOLE LOGS TO HELP US KEEP TRACK OF THE MATH THAT IS OCCURING
          console.log("CHANGE DUE: " + change)
          console.log("Type of Change: " + Register.money[i].name + "\n" + "Units of Change: " + Register.amountsOf[i].amount)
          // console.log("Less or Equal to Change Due: " + Register.money[i].value)
        
          // SET UP A RECURSIVE LOOP
          // RUNS UNTIL WE REACH OUR CONDITION OR CANNOT
          while (change > 0) {

            // Set up a number to keep track of each iteration through loop
            num++

            // RECURSIVELY DECREASE THE AMOUNT OF THE TYPE OF TENDER
            // SO IF WE RUN OUT WE CAN MOVE TO THE NEXT SMALLER 
            // DENOMINATION
            updatedAmt = (Register.amountsOf[i].amount - num);
            amt = updatedAmt;
            console.log("AMOUNT OF TENDER: " + amt)

            // Recursively update the amount of change still needed
            updatedChange = (change - datMon)

              // ROUND TO DECIMAL PLACE
              // TO AVOID OFF BY ONE ERRORS :)
              fixedChange =  Number((updatedChange).toFixed(2))

            // UPDATED CHANGE THAT WILL BE USED
            // ON THE NEXT RECURSIVE LOOP
            change = fixedChange;

            console.log("CHANGE STILL DUE " + change)

              // CHECK IF WE RAN OUT OF THE TYPE OF TENDER REQUIRED
            
              // ????????????????????????????????????????????????????????
              // ????????????????????????????????????????????????????????
              // ????????????????????????????????????????????????????????

              // STUCK HERE
              // HOW DO I ITERATE TO THE NEXT DENOMINATION OF TENDER???
              if (amt === 0 && change > 0) {
                console.log("WE ARE OUT OF " + Register.money[i].name)
                datMon = Register.money[i+1].value;
                console.log("if 0: " + datMon)
                return datMon
              }

            // IF CHANGE IS 0
            // ALL THE MONEY MUST HAVE BEEN GIVEN BACK 
            // ADD THE OBJECT TO THE RESULT OBJECT
            else if (change === 0) {
              console.log("WE MADE IT BABY!!!")

              objArr.push(Register.money[i].name)
              objArr.push(Register.money[i].value * num)
              console.log("OBJ ARR: " +objArr)
              
              // RETURN THE RESULT OBJECT
              Result.status = "OPEN"
              Result.change.push(objArr)
              return Result;
            }

          }
        
        }

    }

  }
  
  // Here is your change, ma'am.
  Result.status = "OPEN";
  return Result;
};


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

Hi,

Generally it helps others help you if you start a topic using the Ask for Help button in the challenge. That will start the topic with a link to the challenge as well as inserting your code automatically. Also, clarifying which tests your code is / is not passing is very useful too. Ok - nag time over.

I couldn’t trace your code out just by looking at it. (I kinda got lost in which variable referred to which value - amt, change, etc.) so I couldn’t figure how to trigger moving on to the next denomination.

I remember this challenge. I don’t recall the exact details but my solution logic worked something like this

Starting with hundreds working downward through each denomination

for(largest to smallest denomination) {

   while( change still due  > this denomination && still have this denomination in drawer){
      hand back one more bill / coin
      do a little math to adjust the change already handed out, change still due back, and money still in drawer
   }

   record how much of this denomination paid out to resultant object
}

return resultant object (the change paid out)

Would a similar while test trigger your code to move on to next denomination?

This is a tough challenge but it really looks like your almost there. Good luck.

Yeah sorry the Ask for Help button seemed to be broken on this particular challenge :confused:

I’ll give your approach a try and see if I can tackle it a different way.

Thanks!