Help with recursive function for Exact Change

Help with recursive function for Exact Change
0

#1

WARNING: RUNNING THIS CODE WILL CRASH YOUR BROWSER
For some reason, when I run the recursive function I have below in my function, my browser crashes and which is most likely due to infinite loop or the max call stack size being exceeded. This is my code for Exact Change. However, I am not looking for the solution to the algorithm, but only the solution to fixing my code or more precisely my function.

I’m utilizing the recursive function in my code because I am trying to take the total change and subtract the selected currency value from the total change until either it can no longer be subtracted from the total because it will result in a negative number or zero or there is no longer anymore of that form of payment(which is given as an argument). In the code, I test this is only one array item not all of them simultaneously.

function checkCashRegister(price, cash, cid) {
  
    var currencyValues = {
    "PENNY": 0.01,
    "NICKEL": 0.05,
    "DIME": 0.1,
    "QUARTER": 0.25,
    "ONE": 1,
    "FIVE": 5,
    "TEN": 10,
    "TWENTY": 20,
    "ONE HUNDRED":100
  };
  
  //----------FIXED AND WORKS NOW------------------------
  var singleArr = [];
  var reverseCID = cid.reverse();
  
 for (var i = 0; i < reverseCID.length; i++) {
    if (currencyValues[reverseCID[i][0]] <= cash - price) {
      singleArr.push(reverseCID[i]);
    }
  }//for loop
  //-------------------------------------------------------
  
  var arbNum = 100;
  var fake = [];
  
  var currencyVal = currencyValues[singleArr[2][0]];
  var totalOfCurrVal = singleArr[2][1];//2 is Nickel
  
  var test = function(total,totalCurr) {
    if (totalCurr === totalOfCurrVal && (total > 0 && total - currencyVal <= 0) || total === 0) {
      fake.push([total, currencyVal]);
    }
    
    var accum = totalCurr + currencyVal;
    var subtract = total - currencyVal;
    return test(subtract,accum);
  };
  
  return test(arbNum,0);
  
}
// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.10],
// ["QUARTER", 4.25],
// ["ONE", 90.00],
// ["FIVE", 55.00],
// ["TEN", 20.00],
// ["TWENTY", 60.00],
// ["ONE HUNDRED", 100.00]]
checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]);


#2

Your recursive function is missing a return statement based on some condition which defines when to stop call itself. It basically keeps calling itself until the stack maxes out.


#3

Considering that I want to only push certain values when the condition is met, how would I go about returning a value or “breaking” the function without returning a value when the condition is met? Also, I just tried adding a return statement and the browser still crashed.


#4

I added a console.log inside the test function, so you could see what is happening to the values of variables total and totalCurr. Run it and it will max out the stack, but then scroll to the top of the console section and you can see why your if statement condition never evaluates to true.

Once you figure out your logic and calculation issues, you still need to return the fake array within this function to escape the function and stop the recursion.


#5

Ok, so the if statement is never true because “got here” is never logged into the console meaning the condition is never met.
Like I said earlier,

What would the if statement look like?

It definitely needs to include totalCurr === totalOfCurrVal. Also, i would want to check if the total is equal to zero. However, if I say total <= 0, it will return the a negative number as the total because it will return the first time the total is less than or equal to zero. I used (total > 0 && total - currencyVal <= 0) || total === 0) to try and fix that hole, but I guess it doesn’t work. How would I go about doing the if statement condition?


#6

I updated the repl.it above with several more console.log statements so you can see how the if statement you just suggested pans out. I suggest modifying these console.log statements to reflect anything you want to test out in your own solution, so you can see the evaluations and understand why the condition you write does not evaluate to true.

Keep trying. If you get closer but can still not figure it out, I will give you a bigger clue.


#7

Alright thank you for all the help. I will try tomorrow and I will come back if I have an answer or any questions.


#8

After messing with my code, I have finally found the desired solution.

function checkCashRegister(price, cash, cid) {
  
    var currencyValues = {
    "PENNY": 0.01,
    "NICKEL": 0.05,
    "DIME": 0.1,
    "QUARTER": 0.25,
    "ONE": 1,
    "FIVE": 5,
    "TEN": 10,
    "TWENTY": 20,
    "ONE HUNDRED":100
 

 };
  
  //----------FIXED AND WORKS NOW------------------------
  var singleArr = [];
  var reverseCID = cid.reverse();
  
 for (var i = 0; i < reverseCID.length; i++) {
    if (currencyValues[reverseCID[i][0]] <= cash - price) {
      singleArr.push(reverseCID[i]);
    }
  }//for loop
  //-------------------------------------------------------
  var arbNum = 2.91;
  var fake = [];
  
  var currencyVal = currencyValues[singleArr[2][0]];
  var totalOfCurrVal = singleArr[2][1];//2 is Nickel
  
  var test = function(sumTotal,totalCurr) {
    console.log('totalOfCurrVal = ' + totalOfCurrVal + '\ntotalCurr = ' + totalCurr + '\nsumTotal = ' + sumTotal);
    console.log();
    if (totalCurr === totalOfCurrVal || sumTotal - currencyVal <= 0) {
      if (sumTotal - currencyVal === 0) {
        //stop everything
        fake.push([sumTotal - currencyVal, currencyVal]);
        return fake;
      }

      
      console.log('got here');
      fake.push([sumTotal, currencyVal]);
      return fake;
    }
    totalCurr = totalCurr + currencyVal;
    totalCurr = (totalCurr.toFixed(2))/1
    sumTotal = sumTotal - currencyVal;
    sumTotal = (sumTotal.toFixed(2))/1
    return test(sumTotal,totalCurr);
 

 };
  
  return test(arbNum,0);
  
  
  
  //return 0.049999999999999684 .toFixed(2) - 0.05;
  
  //someNumber = (someNumber.toFixed(2))/1
}
// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.10],
// ["QUARTER", 4.25],
// ["ONE", 90.00],
// ["FIVE", 55.00],
// ["TEN", 20.00],
// ["TWENTY", 60.00],
// ["ONE HUNDRED", 100.00]]
checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]);

However, I have only solved one piece of the puzzle. I want this function to run for every element in singleArr and I want the total to be a global variable so that the value is preserved in each iteration of the array and not local to each iteration. I could use a for loop, but as you said before, I need to return a value for the recursive function, but that would interfere with the for loop.