JavaScript Algorithms and Data Structures Projects - Cash Register

Hi .

Thanks in advance for any help. I know this is part of the final test but now I’ve passed I thought I’d ask for some guidance.

…so I really struggled with this one!! I appreciate my code may not be great but I finally got it to pass!! ( and you should have seen it before I tried to tidy it up).

The (main) issue was down to trying to work with the decimals contained in the original array. I just couldn’t understand why it wasn’t working until I caught a few stray .9999999997’s on the console checks. I have looked at other posts (guess a few people struggled with this) and appreciate (though don’t necessarily understand) it is caused by how computers deal with decimals.

However I cant find advice on what to do when faced with this. should you never try and work with decimals? Should you always change to integers as I have done and then change back at the end? Are there any other things to look at when faced with numbers that aren’t integers?

Thanks again in advance. Any comments or advice on the code welcome, but to be honest cant tell you how happy I am to finally have it pass,

Your code so far

function checkCashRegister(price, cash, cid) {

// find change owed in cents

let owed = Math.round((cash - price) * 100);
console.log(owed + " owed in cents");

//  set up an available cash array in cents to avoid the constant errors. 
  
let availableCash = cid.map(([a,b]) => [a,b*100]);
//check  console.log(availableCash)
//check  console.log(cid)


// find total amount in till in cents
let till = 0;
for (let i = 0; i < availableCash.length; i++){
  till += Math.round(availableCash[i][1]);
}
console.log(till + " cents in the till");


// return early if owed matches change in till

if (owed == till){
  return {status: "CLOSED", change: cid}
}
//check  console.log(availableCash);



//setup key to work out values of individual coins and notes
  
  let changeKey = {
    "PENNY": 1,
    "NICKEL": 5,
    "DIME": 10,
    "QUARTER": 25,
    "ONE": 100,
    "FIVE": 500,
    "TEN": 1000,
    "TWENTY": 2000,
    "ONE HUNDRED": 10000
  }

//check console.log(changeKey[availableCash[3][0]])


// cycle through to find maximum values of change and push to new array

let total = 0;
  let returnArr = []
  
for (let i = availableCash.length-1; i >= 0; i--){
  let runningTotal = 0;
  while (total <= owed && total + changeKey[availableCash[i][0]] <= owed && availableCash[i][1] > 0) {
    runningTotal += changeKey[availableCash[i][0]];
    total += changeKey[availableCash[i][0]];
    availableCash[i][1] = availableCash[i][1] - changeKey[availableCash[i][0]];

    }

    if (runningTotal > 0) {
    returnArr.push([availableCash[i][0], runningTotal / 100]);
    } 
  }

    if (total == owed){
      return {status: "OPEN", change: returnArr}
    } else {

    return {status: "INSUFFICIENT_FUNDS", change: []};
    }
}

console.log(checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]));



Your browser information:

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

Challenge: JavaScript Algorithms and Data Structures Projects - Cash Register

Link to the challenge:

It really depends upon what you are doing with those decimals.

For something like this where you need exact values, using integers or a fixed format is the way to go.

If you can tolerate some error (many applications can), then you can just use decimals as is.

Here’s an article which explains the basic issues of and reasons for floating point imprecision.

There are various ways of overcoming this (including JS libraries), but one well-worn (but not infallible) trick is the following:

console.log(0.1 + 0.2) // 3.0000000000000004
console.log(Math.round((0.1+0.2)*1000000000000)/1000000000000) // 0.3

It has the benefit of being extremely simple to implement. I used this for my React Calculator project (Front-End Libraries), to calculate each arithmetical operation as accurately as possible.

For the Cash Register project, you can simply use methods such as toFixed(2) or similar, to constrain those unwieldy decimal numbers to 2 decimal places.

Thanks so much for the replies.