Cash Register Not Returning Expected Output

Cash Register Not Returning Expected Output
0

#1

I’m about to go cross-eyed on the Cash Register challenge, so I think it’s time to ask for help. This is where I’m at:


  let transaction = {
    status: '',
    change: [ /*
  ["ONE HUNDRED", 0],
  ["TWENTY", 0],
  ["TEN", 0],
  ["FIVE", 0],
  ["ONE", 0],
  ["QUARTER", 0],
  ["DIME", 0],
  ["NICKEL", 0],
  ["PENNY", 0], */
] };

  const currencyValue = [100, 20, 10, 5, 1, 0.25, 0.10, 0.05, 0.01];
  var changeDue = cash - price;
  var cidSubTotal = 0;
  var cidTotal;


  cid.forEach((drawer) => {
    cidSubTotal += (drawer[1] * 100);
  });

  cidTotal = cidSubTotal / 100;

   var comparisonDrawer = cid.reverse();

  if (changeDue > cidTotal) {
    transaction.status = "INSUFFICIENT_FUNDS";
    transaction.change = [];
  }

  if (cidTotal === changeDue) {
    transaction.status = "CLOSED";
    transaction.change = cid;
  }



  while (transaction.status === '') {
    let index = 0;
    /* -Iterate over the currencyValue array, checking
        the current index versus the value of the changeDue value.

        -If the currencyValue[i] is less than the changeDue AND the corresponding denomination in the comparisonDrawer is positive, perform the following steps:
          -Decrement the comparison drawer by the currencyValue amount
          -Increment the change array by the currencyValue amount.



        -Else the currencyValue is greater than the changeDue, increment the index
        so the next smallest denomination can be checked.

    */
    if (changeDue === 0 && cidTotal > 0) {
      transaction.status = "OPEN";
    }

  }

console.log(transaction);
return transaction;
}

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

There’s obviously a lot of room for improvement here, but I’m concerned with one thing at the current moment: why isn’t this passing in the case of exact change? It was doing so earlier, but I can’t see why it isn’t returning the change array as the cid array, like it’s assigned.


Cash Register: While loop not exiting when expected
#2

Have you tried to console.log() the values of cidTotal and changeDue just prior to setting the values for exact change?


#3

The problem isn’t either of those values, the problem is that when transaction is outputted in this particular case, the value of transaction.change is assigned the value of cid. This prints out out cid, but reversed, which doesn’t make any sense, because I can’t see where I’m reversing …oh that’s weird. I assumed that .reverse() returned a copy of the array, but it doesn’t. I just had to move it to underneath the checks for exact change and insufficient change, and it’s back to behaving as expected. Thanks!


#4

I have been staring at this problem for far too long, and this is where I 'm at: I have the edge cases of there not being enough cash in the drawer at the outset and the case of exact change taken care of. The thing I’m having the most trouble with is the case of returning 'insufficient funds as soon as it’s clear that (while iterating over the drawer) the drawer doesn’t have enough change. I thought the check I put in there would have been enough for that, but it’s not working. Code is:

PS: I realize looking at this that I’m handling the cases of non-exact change completely wrong in this, so no need to mention that :slight_smile:

function checkCashRegister(price, cash, cid) {

  let transaction = {
    status: '',
    change: [
  ["ONE HUNDRED", 0],
  ["TWENTY", 0],
  ["TEN", 0],
  ["FIVE", 0],
  ["ONE", 0],
  ["QUARTER", 0],
  ["DIME", 0],
  ["NICKEL", 0],
  ["PENNY", 0],
]};

  const currencyValue = [100, 20, 10, 5, 1, 0.25, 0.10, 0.05, 0.01];
  var changeDue = cash - price;
  var cidSubTotal = 0;
  var cidTotal;

  cid.forEach((drawer) => {
    cidSubTotal += (drawer[1] * 100);
  });

  cidTotal = cidSubTotal / 100;

  if (changeDue > cidTotal) {
    transaction.status = "INSUFFICIENT_FUNDS";
    transaction.change = [];
  }

  if (cidTotal === changeDue) {
    transaction.status = "CLOSED";
    transaction.change = cid;
  }

  while (transaction.status == '') {
    let i = 0;
    /* moves the sequence forward if the current denomination is greater than the change due, or if the corresponding denomination doesn't exist in the drawer */
    if (currencyValue[i] > changeDue || (currencyValue[i] < changeDue && comparisonDrawer[i][1] < 0)) {
      i++;
    }

    // Takes money from the drawer if current denomination is less than change due, and there is money in the corresponding drawer.
    // Increments requisite value in the change array, and decrements it from the cidTotal value.
    if (currencyValue[i] < changeDue && comparisonDrawer[i][1] > 0) {
      transaction.change[i][1] += Math.Round(currencyValue * 100) / 100;
      cidTotal -= Math.Round(currencyValue * 100) / 100;
    }


    if (i === 9) {
        transaction.status = "INSUFFICIENT_FUNDS";
        transaction.change = [];
    }
    if (changeDue === 0) {
      transaction.status = "OPEN";
      transaction.change.reverse();
    }

  }

return transaction;
}

checkCashRegister(19.5, 20,
  [["PENNY", 0.01],
  ["NICKEL", 0],
  ["DIME", 0],
  ["QUARTER", 0],
  ["ONE", 1],
  ["FIVE", 0],
  ["TEN", 0],
  ["TWENTY", 0],
  ["ONE HUNDRED", 0]]);

#5

staring at a problem without any console.logs is hard.
How about adding some and tracking the variables and their values?
(and tracking conditionals too to see which are getting executed and which are not?)


Cash Register: While loop not exiting when expected
#6

adding console.log statements to the code in the while loop just hangs when I run the file, so I must have an infinite loop or no clear exit for the while condition in there somewhere


#7

It looks like you are handling the insufficient funds scenario well enough.

I gave your code this:
checkCashRegister(18.5, 20,
[[“PENNY”, 0.01],
[“NICKEL”, 0],
[“DIME”, 0],
[“QUARTER”, 0],
[“ONE”, 1],
[“FIVE”, 0],
[“TEN”, 0],
[“TWENTY”, 0],
[“ONE HUNDRED”, 0]]);

and it gave me back
{ status: ‘INSUFFICIENT_FUNDS’, change: [] }

That result seems to be correct in this case.


#8

where is this array defined? I couldn’t find it in your code.


#9

also this:

  while (transaction.status == '') {
   let i = 0;

You are constantly resetting i to 0 in the loop. I’m pretty sure you want that line to be outside the loop.


#10

Ugh, good catch, thanks for help on this and 9ther things today!


#11

Ok, refactored this and am REALLY close to passing, except for test case #3. I’m trying to make sure the passed in value is normalized as far as rounding, but testing shows that it’s not working, at least not in terms of rounding up? I’m off by a penny here, console.log is:

{ status: 'OPEN',
  change:
   [ [ 'TWENTY', 60 ],
     [ 'TEN', 20 ],
     [ 'FIVE', 15 ],
     [ 'ONE', 1 ],
     [ 'QUARTER', 0.5 ],
     [ 'DIME', 0.2 ],
     [ 'PENNY', 0.03 ] ] }

Relevant code is here:

 while (changeDue >= currencyValue[i] && cid[i][1] > 0) {
      changeDue -= currencyValue[i];
      cid[i][1] -= currencyValue[i];
      currentDenomination += (currencyValue[i] * 100) / 100;
    }

    if (currentDenomination > 0) {
      transaction.change.push([cid[i][0], currentDenomination]);
    }

Using the rounding strategy of multiplying the value when adding to the subtotal(currentDenomination), then dividing it by 100 is working just fine earlier in the code, so I’m not sure why it isn’t working here.


#12

I also tried:

   while (changeDue >= currencyValue[i] && cid[i][1] > 0) {
      changeDue -= currencyValue[i];
      cid[i][1] -= currencyValue[i];
  currentDenomination += (currencyValue[i] * 100);
}

if (currentDenomination > 0) {
  currentDenomination = currentDenomination / 100;
  transaction.change.push([cid[i][0], currentDenomination]);
}
...to no avail

#13

Console logging confirms that the problematic value is the “changeDue” amount, which fractures into decimal craziness as soon as it starts getting decremented. All other values exhibit “expected” behavior.


#14

And finally solved this: the key was stablizing the changeDue value exactly in the way I stabilized the cidSubTotal value earlier in the algorithm. Thanks for the help from everybody who weighed in! hbar1st and snowmonkey, your suggestion on console.logging values was key here; I hadn’t been in the habit of doing that much before, but it’s pretty useful when you have to make granular progress on problems like this one.