FreeCodeCamp JavaScript CashRegister Solution

FreeCodeCamp JavaScript CashRegister Solution

If you're looking for a solution to the FreeCodeCamp JavaScript CashRegister challenge, you're in the right place. I recently completed this challenge myself and wanted to share my solution with you.

The CashRegister challenge asks you to create a function that takes in a purchase price and a cash amount and returns the amount of change due, as well as the exact change due in the form of an array of denominations.

My Solution

My solution to this problem involves breaking down the cash amount into its constituent denominations and using those denominations to make change for the purchase price. Here's how it works:


function checkCashRegister(price, cash, cid) {
  var change = cash - price; // calculate the amount of change due
  var currency = [ // define an array of denominations and their values
    ["PENNY", 0.01],
    ["NICKEL", 0.05],
    ["DIME", 0.1],
    ["QUARTER", 0.25],
    ["ONE", 1],
    ["FIVE", 5],
    ["TEN", 10],
    ["TWENTY", 20],
    ["ONE HUNDRED", 100]
  ];
  var changeArr = []; // initialize an array to hold the change due
  var cidTotal = 0; // initialize a variable to hold the total amount of cash in the cash drawer

  // loop through each denomination, starting with the highest
  for (var i = currency.length - 1; i >= 0; i--) {
    var denominationName = currency[i][0]; // get the name of the denomination
    var denominationValue = currency[i][1]; // get the value of the denomination
    var denominationAvailable = cid[i][1]; // get the amount of cash available in the cash drawer for this denomination
    var denominationCount = 0; // initialize a variable to hold the number of this denomination to give as change

    // while there is still change due, and there is still this denomination available, and the value of this denomination is less than or equal to the change due
    while (change >= denominationValue && denominationAvailable > 0) {
      change -= denominationValue; // subtract the value of this denomination from the change due
      change = Math.round(change * 100) / 100; // round the change due to two decimal places
      denominationAvailable -= denominationValue; // subtract the value of this denomination from the amount available in the cash drawer
      denominationCount++; // increase the number of this denomination to give as change
      cidTotal += denominationValue; // increase the total amount of cash in the cash drawer
    }

    // if we gave any of this denomination as change, add it to the changeArr array
    if (denominationCount > 0) {
      changeArr.push([denominationName, denominationCount * denominationValue]);
    }
  }

  // if there is still change due, or if the cash drawer doesn't have enough cash to make change, return "Insufficient Funds"
  if (change > 0 || cidTotal < change) {
    return "Insufficient Funds";
  }

  // if we were able to make change, and we used up all the cash in the cash drawer, return "Closed"
  if (cidTotal === change) {
    return "Closed";
  }

  // otherwise, return the array of denominations used to make change
  return changeArr;
}

console.log(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]]));
    

My solution uses a while loop to calculate how many of each denomination of currency to give as change. It also rounds the change due to two decimal places using the Math.round() function to avoid floating point errors.

If the cash drawer doesn't have enough cash to make change, the function returns "Insufficient Funds". If we were able to make change, and we used up all the cash in the cash drawer, the function returns "Closed". Otherwise, it returns an array of denominations used to make change.

Alternative Solution

Another approach to this problem is to use recursion to calculate how many of each denomination of currency to give as change. This approach involves defining a recursive function that takes in the change due, the currency array, and an index indicating which denomination to use.


function makeChange(change, currency, index) {
    if (change === 0) {
        return [];
    }
    if (index === currency.length) {
        return null;
    }
    var denomName = currency[index][0];
    var denomValue = currency[index][1];
    var maxCount = Math.floor(change / denomValue);
    for (var i = maxCount; i >= 0; i--) {
        var remainingChange = change - i * denomValue;
        var result = makeChange(remainingChange, currency, index + 1);
        if (result !== null) {
            if (i > 0) {
                result.push([denomName, i * denomValue]);
            }
            return result;
        }
    }
    return null;
}

function checkCashRegister(price, cash, cid) {
    var changeDue = cash - price;
    var currency = [
        ["PENNY", 0.01],
        ["NICKEL", 0.05],
        ["DIME", 0.1],
        ["QUARTER", 0.25],
        ["ONE", 1],
        ["FIVE", 5],
        ["TEN", 10],
        ["TWENTY", 20],
        ["ONE HUNDRED", 100]
    ];
    var cidTotal = cid.reduce(function(acc, val) {
        return acc + val[1];
    }, 0);
    if (cidTotal < changeDue) {
        return "Insufficient Funds";
    }
    if (cidTotal === changeDue) {
        return "Closed";
    }
    var change = makeChange(changeDue, currency, 0);
    if (change === null) {
        return "Insufficient Funds";
    }
    return change;
}

console.log(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]]));
    

This approach uses recursion to calculate how many of each denomination of currency to give as change, starting with the highest denomination and working down. It returns an array of denominations used to make change, or "Insufficient Funds" if there isn't enough cash in the cash drawer to make change, or "Closed" if we were able to make change and use up all the cash in the cash drawer.

These are just two possible solutions to the FreeCodeCamp JavaScript CashRegister challenge. There are many other ways to approach this problem, so feel free to experiment and find the solution that works best for you.

Subscribe to The Poor Coder | Algorithm Solutions

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
[email protected]
Subscribe