JavaScript Algorithms and Data Structures Projects: Cash Register (need help debugging!)

I’ve been working on this algorithm for a couple hours now and could use some help debugging my code. I’ve passed all test-cases except for the 3rd one from the top. It also says I failed the last test case but when I run the function with the test-case parameters I get the correct output but for some reason it’s saying I failed. At this point I’m not sure if it’s my code or something wrong with the site…would really appreciate some help! Thanks!

Your code so far


function checkCashRegister(price, cash, cid) {
  let change = cash-price
  let totalCid = 0
  let status = {status:'', change: []}

  let cidObj = {
    "PENNY": .01,
    "NICKEL": .05,
    "DIME": .1,
    "QUARTER": .25,
    "ONE": 1,
    "FIVE": 5,
    "TEN": 10,
    "TWENTY": 20, 
    "ONE HUNDRED": 100}

  for (let i = 0 ; i < cid.length; i++){
    totalCid += cid[i][1]
  }

  totalCid = Number(totalCid.toFixed(2))
 
  if (change === totalCid){
    status.status = "CLOSED"
    status.change.push(cid)
    return status
  } else if (totalCid < change){
    status.status = "INSUFFICIENT_FUNDS"
    status.change = []  
  } else {
      for (let i = cid.length-1 ; i >= 0; i--){
        if (change >= cidObj[cid[i][0]] && change >= cid[i][1]){
          status.change.push(cid[i])
          change -= cid[i][1]

        } else if (change >= cidObj[cid[i][0]] && change < cid[i][1]){
            let amount = Math.floor(change/cidObj[cid[i][0]])*cidObj[cid[i][0]]

            status.change.push([cid[i][0], amount])
            change -= amount
        }
      } 
  }
  
  change = Math.round(change * 100) / 100;

  if (change !== 0){
    status.status = "INSUFFICIENT_FUNDS"
    status.change = []
  } else {
    status.status = "OPEN"
  }
  return status;
}


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

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 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36.

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

At a quick glance, one thing does jump out. If the change due equals the total in the register, you’re pushing cid onto the status.change array. This is wrong, as it makes status.change an array containing another array of arrays.

Just set status.change to cid rather than pushing anything.

1 Like

Thanks for the help! I figured out the issue was a precision error in my calculations. I had to set change = Math.round(change*100)/100 after subtracting whatever amount of change.

In the example below:

price = $3.26
cash = $100
change = $96.74
cid = [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]] 

when my function loops thru ‘cid’, it will first subtract $60 from change which should equal 96.74-60 = 36.74. However, for some reason JS gives me back 36.739999999999995. Hence, the need to set change = Math.round(change*100)/100 after each subtraction.

Does anyone know why JS gives me back 36.739999999999995 as opposed to just 36.74 when we calculate 96.74-60? This calculation makes no sense to me and is what thru my whole algorithm off. My final solution is below:

function checkCashRegister(price, cash, cid) {
  // figure out change amount due:
  let change = cash-price
  let totalCid = 0
  let status = {status:'', change: []}

  let cidObj = {
    "PENNY": .01,
    "NICKEL": .05,
    "DIME": .1,
    "QUARTER": .25,
    "ONE": 1,
    "FIVE": 5,
    "TEN": 10,
    "TWENTY": 20, 
    "ONE HUNDRED": 100}

  // figure out total of cid
  for (let i = 0 ; i < cid.length; i++){
    totalCid += cid[i][1]
  }

  totalCid = Math.round(totalCid * 100) / 100;
 
  if (change === totalCid){
    status.status = "CLOSED"
    status.change = cid
    return status
  }
  else if (totalCid < change){
    status.status = "INSUFFICIENT_FUNDS"
    status.change = []  
  }
  
   else {
      for (let i = cid.length-1 ; i >= 0; i--){
        if (change >= cidObj[cid[i][0]] && change >= cid[i][1]){
          status.change.push(cid[i])
          change -= cid[i][1]
          change = Math.round(change*100)/100


        } else if (change >= cidObj[cid[i][0]] && change < cid[i][1]){
            let amount = Math.floor(change/cidObj[cid[i][0]])*cidObj[cid[i][0]]

            status.change.push([cid[i][0], amount])
            change -=  amount
            change = Math.round(change*100)/100
        }
      } 
  }
  
  if (change >= .01){
    status.status = "INSUFFICIENT_FUNDS"
    status.change = []
  } else {
    status.status = "OPEN"
  }

  return status;
}

The workaround i use:

Number( change.toFixed(2) );

Easy precision.

1 Like