Cash Register failing some of the tests

Tell us what’s happening:

Hi,
I’m struggling to finish the cash register challenge. The following code isn’t very elegant, but it works fine on Repl as far as I can tell, all tests return exactly what they should, but I keep failing three of the tests when I run the code on freeCodeCamp. Is there anything wrong with my code?

Many thanks for any help!
Stepan

Your code so far


// lits of denominations
let values = [ ["PENNY", 0.01], ["NICKEL", 0.05], ["DIME", 0.1], ["QUARTER", 0.25], ["ONE", 1], ["FIVE", 5], ["TEN", 10], ["TWENTY", 20], ["ONE HUNDRED", 100]]

// variables used in the functions
let drobne = [];
let changeRegister = [];
let notEnoughCash = 0;

// ensures theres only one of each denomination in the return
function prettyFormat (arr) {
  let res = [["ONE HUNDRED", 0], ["TWENTY", 0], ["TEN", 0], ["FIVE",0], ["ONE",0], ["QUARTER",0], ["DIME", 0], ["NICKEL", 0], ["PENNY", 0]];
  for (let j = 0; j < res.length; j++) {
    for (let k = 0; k < arr.length; k++) {
      if (res[j][0] == arr[k][0]) {
        res[j][1] = res[j][1] + arr[k][1];
      }
    }
  }
  return strip(res);
}

// removes denominations with zero cash
function strip (res) {
  let stripped = [];
  for (let l = 0; l < res.length; l++) {
    if (res[l][1] > 0) {
      stripped.push([res[l][0],res[l][1]])
    }
  }
  return stripped;
}

// returns value of selected denomination
function getValue(name) {
  for (let i = 0; i < values.length; i++) {
    if (name == values[i][0]) {
      return values[i][1]
    }
  }
}

// loops through change register until there is still money to be returned
function checkHighest(returnCash) {
  if (changeRegister.length == 0) {
    // in case it's impossible to return the exact amount
    notEnoughCash = 1;
  } else if (returnCash < getValue(changeRegister[0][0])) {
      // if the cash to be return is less the largest denomination ,remove the denomination as it's not needed and loop again
      changeRegister.shift();
      checkHighest(returnCash)
  } else {
    // adds biggest denomination to the "drobne" array which stores the denominations which should be returned
    let banknote = getValue(changeRegister[0][0])
    drobne.push([changeRegister[0][0],banknote])
    if (changeRegister[0][1] <= getValue(changeRegister[0][0])) {
      // if the returned bankonet was the last of its denomination in the change register, remove it
      changeRegister.shift()
    } else {
      // otherwise just decrease the total amount
      changeRegister[0][1] = changeRegister[0][1] - banknote
    }
    // remove denomination from the amount to be returned
    returnCash = (returnCash - banknote).toFixed(2);
    if (returnCash > 0.009) {
      //loop again if not complete
      checkHighest(returnCash)
    } 
  }
  if (notEnoughCash == 1) {
    return {status: "INSUFFICIENT_FUNDS", change: []}
  } else {
    return {status: "OPEN", change: prettyFormat(drobne)}
  }
}


function checkCashRegister(price, cash, cid) {
  // calculate how much needs to be returned and how much money is in the cash register
  let returnCash = cash - price;
  let totalCash = 0;
  for (let i = 0;i<cid.length;i++) {
    totalCash = totalCash + cid[i][1]
  }
  
  if (returnCash > totalCash) {
    // if there is not enough money
    return {status: "INSUFFICIENT_FUNDS", change: []}
  } else if (returnCash == totalCash) {
    // if there is an exact amount of money
    return {status: "CLOSED", change:cid}
  } else {
    // ensure the change register is sorted from the largest denominations and all denominations with zero total value are removed
    for (let j = cid.length-1; j >= 0; j--) {
      changeRegister.push(cid[j])
    }
    changeRegister = prettyFormat(changeRegister)
    return checkHighest(returnCash)
  }
}

Your browser information:

User Agent is: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:62.0) Gecko/20100101 Firefox/62.0.

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

I think your tests are influencing one another, it’s best if you keep all your variables inside the function, that way its scope is limited to each call of that function.

I made your test pass by doing this:

  1. Copy all your code.
  2. Reset the code in the challenge window.
  3. Replace everything inside the default function with your code.
  4. Remove this line function checkCashRegister(price, cash, cid) { (the one you declared, near the bottom).
  5. Remove the closed bracket } from that function (is in the bottom).

Just in case you couldn’t follow the instructions along I’m pasting here:

function checkCashRegister(price, cash, cid) {
  // lits of denominations
  let values = [
    ["PENNY", 0.01],
    ["NICKEL", 0.05],
    ["DIME", 0.1],
    ["QUARTER", 0.25],
    ["ONE", 1],
    ["FIVE", 5],
    ["TEN", 10],
    ["TWENTY", 20],
    ["ONE HUNDRED", 100]
  ];

  // variables used in the functions
  let drobne = [];
  let changeRegister = [];
  let notEnoughCash = 0;

  // ensures theres only one of each denomination in the return
  function prettyFormat(arr) {
    let res = [
      ["ONE HUNDRED", 0],
      ["TWENTY", 0],
      ["TEN", 0],
      ["FIVE", 0],
      ["ONE", 0],
      ["QUARTER", 0],
      ["DIME", 0],
      ["NICKEL", 0],
      ["PENNY", 0]
    ];
    for (let j = 0; j < res.length; j++) {
      for (let k = 0; k < arr.length; k++) {
        if (res[j][0] == arr[k][0]) {
          res[j][1] = res[j][1] + arr[k][1];
        }
      }
    }
    return strip(res);
  }

  // removes denominations with zero cash
  function strip(res) {
    let stripped = [];
    for (let l = 0; l < res.length; l++) {
      if (res[l][1] > 0) {
        stripped.push([res[l][0], res[l][1]]);
      }
    }
    return stripped;
  }

  // returns value of selected denomination
  function getValue(name) {
    for (let i = 0; i < values.length; i++) {
      if (name == values[i][0]) {
        return values[i][1];
      }
    }
  }

  // loops through change register until there is still money to be returned
  function checkHighest(returnCash) {
    if (changeRegister.length == 0) {
      // in case it's impossible to return the exact amount
      notEnoughCash = 1;
    } else if (returnCash < getValue(changeRegister[0][0])) {
      // if the cash to be return is less the largest denomination ,remove the denomination as it's not needed and loop again
      changeRegister.shift();
      checkHighest(returnCash);
    } else {
      // adds biggest denomination to the "drobne" array which stores the denominations which should be returned
      let banknote = getValue(changeRegister[0][0]);
      drobne.push([changeRegister[0][0], banknote]);
      if (changeRegister[0][1] <= getValue(changeRegister[0][0])) {
        // if the returned bankonet was the last of its denomination in the change register, remove it
        changeRegister.shift();
      } else {
        // otherwise just decrease the total amount
        changeRegister[0][1] = changeRegister[0][1] - banknote;
      }
      // remove denomination from the amount to be returned
      returnCash = (returnCash - banknote).toFixed(2);
      if (returnCash > 0.009) {
        //loop again if not complete
        checkHighest(returnCash);
      }
    }
    if (notEnoughCash == 1) {
      return { status: "INSUFFICIENT_FUNDS", change: [] };
    } else {
      return { status: "OPEN", change: prettyFormat(drobne) };
    }
  }

  // calculate how much needs to be returned and how much money is in the cash register
  let returnCash = cash - price;
  let totalCash = 0;
  for (let i = 0; i < cid.length; i++) {
    totalCash = totalCash + cid[i][1];
  }

  if (returnCash > totalCash) {
    // if there is not enough money
    return { status: "INSUFFICIENT_FUNDS", change: [] };
  } else if (returnCash == totalCash) {
    // if there is an exact amount of money
    return { status: "CLOSED", change: cid };
  } else {
    // ensure the change register is sorted from the largest denominations and all denominations with zero total value are removed
    for (let j = cid.length - 1; j >= 0; j--) {
      changeRegister.push(cid[j]);
    }
    changeRegister = prettyFormat(changeRegister);
    return checkHighest(returnCash);
  }
}

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

Hi ghukahr,

That’s a great small update, it makes the function much clearer and I can pass the test. Thank you!

Stepan