Cash Register. I'm a little bit stuck!

Tell us what’s happening:

I am having a problem with something occurring on line 73.
After an initial push of [“Twenty”, 2000] to changeArr, this ‘else if’ statement on 72 is met as there is a [“Twenty”] already in the changeArr (which is my final array altering status). However, it adds 1 twenty and not a 2nd like I’m trying to intend, and instead moves onto the next lower currency found within conversion array.

I’ve tried to debug this as when I don’t try use += onto the element in changeArr, the code is executing in the way it should but the moment I increase the looped changeArr by any amount it only executes it once and not the intended two times for the first conversion amount. I have some console.log() prompts already to diagnose as best as I could the algorithm

I have the numbers in integers at the moment as there was a rounding issue but you can un-comment lines 83 && 87 to get it to the correct decimal format for the project.

Also the function inside is only checking if a copy of the first index of an element in conversion exists within changeArr. So this could be [“Penny”]. Based off this information I am then on lines 69 - 74 deciding if I want to push an exact copy from conversion due to no match being found in changeArr, or if there was a copy already existing to += the additional amount to the second index what holds the amount.

Any help is much appreciated and I know this is messy so thank you very much for your time! I wish you the best of luck!

Your code so far

function checkCashRegister(price, cash, cid) {

    // Converting decimals to integers
    price *= 100;
    cash *= 100;
    // converting cid to integer (205 was 204.999999999994 for an unknown reason)
    for (let i = 0; i < cid.length; i++) {
        cid[i][1] *= 100;
        cid[i][1] = Math.round(cid[i][1]);
    }

    // Start of algorithms
    
    let conversion = [["PENNY", 1], ["NICKEL", 5], ["DIME", 10], ["QUARTER", 25], ["ONE", 100], ["FIVE", 500], ["TEN", 1000], ["TWENTY", 2000], ["ONE HUNDRED", 10000]]

    let change = cash - price;

    let changeArr = [];

    let status = {status: "", change: []};
    
    let item = [];
  
    // function to see if an exact copy of conversion[k][0] was found in changeArr executed on line 69
    function isItemInArray(array, item) {
      for (var k = 0; k < array.length; k++) {
          if (array[k][0] == item[0]) {
            return true; // A copy of conversion[k][0] was found in changeArr e.g. ["PENNY"]
          }
      }
      return false; // No copy of conversion[k][0] was found in changeArr
    }
    
    while (change > 0) {
      console.log(`Change due ${change}`)
      for (let i = conversion.length-1; i >= 0; i--) {
        
        // CAN IGNORE THIS WHOLE SECTION AS IT IS ONLY TRUE AT THE LAST LOOP

        // Exact currency is within the Array CID array
        if (conversion[i][1] === change && cid[i][1] >= conversion[i][1]) {
          // check algorithm functions
          change -= conversion[i][1];
          console.log(`Exact! change take away ${conversion[i][1]} (${conversion[i][0]}). New total ${change}`)
          // reduces cash register amount based on change given
          cid[i][1] -= conversion[i][1];
          // pushes amount of change given in blank array       //possible fix for exact amount
          if (changeArr.indexOf(conversion[i]) === -1) {
            changeArr.push(conversion[i])
          // non-push change FIX
          } else if (changeArr.indexOf(conversion[i]) > -1) {
            changeArr[changeArr.indexOf(conversion[i])][1] += conversion[i][1];
          }





        //Exact currency is not in the CID array
        } else if (conversion[i][1] < change && cid[i][1] >= conversion [i][1]) {
          
          change -= conversion[i][1];
          cid[i][1] -= conversion[i][1];
          console.log(`Not exact! change take away ${conversion[i][1]} (${conversion[i][0]}). New total ${change}`)
          item = conversion[i];
          
          // FIX THIS PLEASE!!!
          // Conversion[i][0] is NOT in changeArr
          if (!isItemInArray(changeArr, item)) {
            changeArr.push(conversion[i])
          // Conversion[i][0] in changeArr
          } else if (isItemInArray(changeArr, item)) {
            changeArr[changeArr.indexOf(conversion[i])][1] += item[1];
          }
          //Reset loop at the end to reset back to checking the largest number in conversion can be used
          i = 8;
        }
        
      }
    }
    
    // converting changeArr to decimal
    /*
    for (let i = 0; i < changeArr.length; i++) {
      changeArr[i][1] /= 100;
    }
    */
    console.log(changeArr);
    if (change == 0) {
      status.status = "OPEN",
      status.change = changeArr
      return status;
    }
    
  };

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

Your browser information:

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

Link to challenge: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/cash-register

After some thinking I managed to pinpoint the problem. And add some tape to bandage up the error.

So on line 73


changeArr[changeArr.indexOf(conversion[i])][1] += item[1];

The issue was that using .indexOf would only find the whole of the two dimensional array, and from what I’ve read now, you can’t use .indexOf to do advanced things such as look in an array of two dimensional arrays and return an index of one of the elements within a two dimensional array.

To compensate I change my function and added an index variable so when the function executes it also pushed where it found the first element in the two dimensional array within changeArr.

    
    let itemIndex = undefined;

    function isItemInArray(array, item) {
      for (var k = 0; k < array.length; k++) {
          if (array[k][0] == item[0]) {
            itemIndex = k;
            return true; // A copy of conversion[k][0] was found in changeArr e.g. ["PENNY"]
          }
      }
      return false; // No copy of conversion[k][0] was found in changeArr
    }

And then finally, the bandage! For an unknown reason (spent hours pondering) when using the += operator to increase the value of an element in changeArr such as [“Penny”, 1] to [“Penny”, 2] without pushing anything, my conversion array (just an array with the coin/note values) would increase. So at the very end I’d just reset it after each loop to it’s default value.

Here it is altogether (it’s not finished), but I solved my problem, and have almost finished now!


function checkCashRegister(price, cash, cid) {

    // Converting decimals to integers
    price *= 100;
    cash *= 100;
    // converting cid to integer (205 was 204.999999999994 for an unknown reason)
    for (let i = 0; i < cid.length; i++) {
        cid[i][1] *= 100;
        cid[i][1] = Math.round(cid[i][1]);
    }

    // Start of algorithms
    let conversion = [["PENNY", 1], ["NICKEL", 5], ["DIME", 10], ["QUARTER", 25], ["ONE", 100], ["FIVE", 500], ["TEN", 1000], ["TWENTY", 2000], ["ONE HUNDRED", 10000]]
    let change = cash - price;
    let changeArr = [];
    let status = {status: "", change: []};
    let item = [];
    let itemIndex = undefined;
  
    // function to see if an exact copy of conversion[k][0] was found in changeArr executed on line 69
    function isItemInArray(array, item) {
      for (var k = 0; k < array.length; k++) {
          if (array[k][0] == item[0]) {
            itemIndex = k;
            return true; // A copy of conversion[k][0] was found in changeArr e.g. ["PENNY"]
          }
      }
      return false; // No copy of conversion[k][0] was found in changeArr
    }
    
    while (change > 0) {
      
      console.log(`Change due ${change}`)
      
      for (let i = conversion.length-1; i >= 0; i--) {
        
        // CAN IGNORE THIS WHOLE SECTION AS IT IS ONLY TRUE AT THE LAST LOOP

        // Exact currency is within the Array CID array
        if (conversion[i][1] === change && cid[i][1] >= conversion[i][1]) {
          // check algorithm functions
          change -= conversion[i][1];
          console.log(`Exact! change take away ${conversion[i][1]} (${conversion[i][0]}). New total ${change}`)
          // reduces cash register amount based on change given
          cid[i][1] -= conversion[i][1];
          // pushes amount of change given in blank array       //possible fix for exact amount
          if (changeArr.indexOf(conversion[i]) === -1) {
            changeArr.push(conversion[i])
          // non-push change FIX
          } else if (changeArr.indexOf(conversion[i]) > -1) {
            changeArr[changeArr.indexOf(conversion[i])][1] += conversion[i][1];
          }





        //Exact currency is not in the CID array // change the [2] in 2nd rule
        } else if (conversion[i][1] < change && cid[i][1] >= conversion [i][1]) {
          change -= conversion[i][1];
          cid[i][1] -= conversion[i][1];
          console.log(`Not exact! change take away ${conversion[i][1]} (${conversion[i][0]}). New total ${change}`)
          item = conversion[i];
          
          // FIX THIS PLEASE!!!
          // Conversion[i][0] is NOT in changeArr
          if (!isItemInArray(changeArr, item)) {
            changeArr.push(conversion[i])
          // Conversion[i][0] in changeArr
          } else if (isItemInArray(changeArr, item)) {
            //HERE IS THE ISSUE CAN'T use indexOf as it won't be found again if item[1] is added
            changeArr[itemIndex][1] += item[1];
          }
          //Reset loop at the end to reset back to checking the largest number in conversion can be used
          conversion = [["PENNY", 1], ["NICKEL", 5], ["DIME", 10], ["QUARTER", 25], ["ONE", 100], ["FIVE", 500], ["TEN", 1000], ["TWENTY", 2000], ["ONE HUNDRED", 10000]]
          i = 8;
        }
        
      }
    }
    
    // converting changeArr to decimal
    /* //REMOVE WHEN FIXED
    for (let i = 0; i < changeArr.length; i++) {
      changeArr[i][1] /= 100;
    }
    */
    console.log(changeArr);
    if (change == 0) {
      status.status = "OPEN",
      status.change = changeArr
      return status;
    }
    
  };

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