Human Cyborg Relations
Human Cyborg Relations

Reputation: 1244

Calculating exact change with JavaScript

I'm attempting to solve an algorithm challenge over at FreeCodeCamp.

Here is the prompt for the problem:

Design a cash register drawer function checkCashRegister() that accepts purchase price as the first argument (price), payment as the second argument (cash), and cash-in-drawer (cid) as the third argument.

cid is a 2D array listing available currency.

Return the string "Insufficient Funds" if cash-in-drawer is less than the change due. Return the string "Closed" if cash-in-drawer is equal to the change due.

Otherwise, return change in coin and bills, sorted in highest to lowest order.

My solution works for most of the parameters, except the following:

checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]])

should return: [["QUARTER", 0.50]]

checkCashRegister(3.26, 100.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]])

should return: [["TWENTY", 60.00], ["TEN", 20.00], ["FIVE", 15.00], ["ONE", 1.00], ["QUARTER", 0.50], ["DIME", 0.20], ["PENNY", 0.04]]

function checkCashRegister(price, cash, cid) {
  var change = 100 * (cash - price);
  var availableFunds = 0;

  var moneyValues = [1, 5, 10, 25, 100, 500, 1000, 2000, 10000];
  var amtToReturn = [];

  for (var i = cid.length - 1; i >= 0; i--){
    var amt = 0;
    while (moneyValues[i] <= change && cid[i][1] > 0 && change > 0){
      console.log("subtracting " + moneyValues[i]);
      cid[i][1] -= moneyValues[i]/100; // reduce amount in cid
      change -= moneyValues[i]; // reduce amount from change
      amt += moneyValues[i]/100; // keep track of how much money was taken out of cid
    }
    if (amt !== 0){
      // adds record of amount taken out of cid
      amtToReturn.push([cid[i][0], amt.toFixed(2)]);
    }
  }


  // if there is still some change left over
  if (change !== 0){
    console.log("broke");
    console.log(change);
    return "Insufficient Funds";
  }

  // if there is any money left in cid, it returns amtToReturn
  for (var j = 0; j < cid.length; j++){
    if (cid[j][1] > 0){
      console.log(amtToReturn);
      return amtToReturn;
    }
  }

  // if register is empty
  console.log("closed");
  return "Closed";

}

// Example cash-in-drawer array:
// [["PENNY", 1.01], 0
// ["NICKEL", 2.05], 1
// ["DIME", 3.10],   2
// ["QUARTER", 4.25],3
// ["ONE", 90.00],   4
// ["FIVE", 55.00],  5
// ["TEN", 20.00],   6
// ["TWENTY", 60.00],7
// ["ONE HUNDRED", 100.00]]8

checkCashRegister(19.50, 20.00, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.10], ["QUARTER", 4.25], ["ONE", 90.00], ["FIVE", 55.00], ["TEN", 20.00], ["TWENTY", 60.00], ["ONE HUNDRED", 100.00]]);

I used the value of money in cents to avoid any floating point precision errors. I feel like there's just a tiny bug somewhere that is preventing me from finishing this problem.

Here is the fiddle: https://jsfiddle.net/odyjcmfj/

Upvotes: 2

Views: 2253

Answers (1)

Arnauld
Arnauld

Reputation: 6130

They're apparently expecting numbers as the second entry of the ["BILL", value] arrays.

Just replace:

  amtToReturn.push([cid[i][0], amt.toFixed(2)]);

with:

  amtToReturn.push([cid[i][0], amt]);

and you should be all set to go.

Upvotes: 1

Related Questions