Cash Register challenge, not passing last test by a penny

I seriously can not believe my luck.

The code passes all of the tests except the 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]]) should return {status: "OPEN", change: [["TWENTY", 60], ["TEN", 20], ["FIVE", 15], ["ONE", 1], ["QUARTER", 0.5], ["DIME", 0.2], ["PENNY", 0.04]]}.

Which doesn´t pass because my code return the same except [“PENNY”, 0.03] instead of [“PENNY”, 0.04] :grimacing:

Basically my code consists in a loop

var reference = 0 //stop loop when reference value becomes 96.74
  for (var i=fromthere; i > -1; i--){
    let counter = quantityofCoins[i]
      for (var j=0; j<counter;j++){
        if (reference > toReturn){
          cidtoReturn[i][1] -= typeofCoin[i]
          reference -= typeofCoin[i]
          break;
        }
        cidtoReturn[i][1] += typeofCoin[i]
        reference += typeofCoin[i]
        
      }
    }

Here are what each variable in the loop means:

“fromthere” it´s just the index from where the loop must start going. Thanks to this code it changes depending to the amount there is to return:

var closest = typeofCoin.reduce(function(prev, curr) {
      return (Math.abs(curr - toReturn) < Math.abs(prev - toReturn) ? curr : prev);
    });
  
    if (toReturn < closest){
      var fromthere = typeofCoin.indexOf(closest) - 1
    }
    else {
      var fromthere = typeofCoin.indexOf(closest)
    }

So in this test fromthere will be 7, which mean the loop will start counting from the “TWENTY” currency, instead from the “HUNDRED”

The rest of variables I use in the loop:

 var toReturn = cash - price

var cidtoReturn = [["PENNY", 0], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE",0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]

var typeofCoin = [0.01,0.05,0.10,0.25,1,5,10,20,100]

 var quantityofCoins = [cid[0][1]/0.01, Math.round(cid[1][1]/0.05), cid[2][1]/0.1,cid[3][1]/0.25, cid[4][1], cid[5][1]/5, cid[6][1]/10, cid[7][1]/20, cid[8][1]/100]

I think the main problem is my code doesn´t actually stop when it reaches exact 96.74 but rather it just substract the last value added if it surpassed toReturn, and then exists the loop. Magically it kind of works but in this case it doesn´t for some reason.

Can I slightly modify it withouth messing the other tests, to actually return the penny left it supposed to return? Or should I change a lot?.

----This is the FULL code in case anybody wants to test it in his machine:

The way you’re reflecting on and explaining your code is great!

And your last couple of questions are really good.

That said, please post your complete code as it appears in your editor as well as a link to the actual exercise.

(The easiest way to do that is, from the actual exercise page, click the “Ask for Help” button, which is a just a couple buttons below the “Run the Tests” button. Then click the “Create a help post on the forum”. Copy the contents from that new forum entry and either modify your original message above or just add it as a new response here.)

2 Likes

The other tactic I will often use for the challenges that hang me up, because the FCC lesson console and editor are kind of limited, I will work with the project on a third-party site like repl.it or codepen – if @Onpointiscake were to put the code somewhere like that where they can test it out and get understandable console output, then the link to that sandbox could be posted, and we could all hammer on it there.

When users post full code, that’s usually my first steps:

  1. set up an empty repl.it for (in this case) javascript;
  2. copy their code and paste it there.
  3. go to the FCC test page, and get the various test calls that will be made, and copy/paste them into my repl.it.

doing so, I can add my own console statements, test things, and see what the output is doing in a somewhat less confusing way.

1 Like

You right man, and i also work on repl.it, now i just post the full code. Hope you can take a look!

Your off-by-a-penny problem doesn’t appear to be a logic problem, rather you’ve run into a common math problem that most (if not all) programming languages, including JavaScript have.


Before I go into detail on that, I would also suggest you refactor your code to get rid of the closest and fromthere logic and instead integrate them directly into your for loop, e.g. (in rough pseudoCode)

const largestCid = last index in cid
for (i = largestCid; toReturn > 0; i--) {
  // evaluate whether you can give some change with the current cid
  //   if so, give the change
  // otherwise move down to the next cid
}

As for the common math problem, open this version of your code, run it, and look at the log output - https://repl.it/@metasean/Onpointiscake-cash-register

What I’ve highlighted (with <-- is a problem) is indicative of decimal (aka floating point) math errors.

I highly, highly, highly recommend you go through https://floating-point-gui.de/ (and definitely run 0.1 + 0.2 in your console to see what the author is talking about). Then read http://adripofjavascript.com/blog/drips/avoiding-problems-with-decimal-math-in-javascript.html.

Once you’ve gone through those two resources, you should have a much better understanding of the underlying problem and how to account for it.

Definitely let us know if you need more help!

2 Likes

Thanks for the work putting into explaining each thing! I´ll see if I can sort it out now!

1 Like