Please review - Exact Change Algorithm

Please review - Exact Change Algorithm
0

#1

Hey guys,

I’ve seen different approaches so far and I’d like to hear some feedback on my code for this challenge. Is it well structured, is everything clear and readable? Does anything confuse you? What could be improved? If you just liked it you can also leave a comment of course. :wink: Thx!


/*jshint esversion: 6 */

function checkCashRegister(price, cash, cid) {
  //declare and initialize variables
  var change = Math.round((cash - price) * 100);
  var value = 0;
  var changeRecord = [];
  var currency = [1, 5, 10, 25, 100, 500, 1000, 2000, 10000];
  //convert all floats to integers due to floating point number issue
  cid.forEach(el => el[1] = Math.round(el[1] * 100));
  //helper function to check if sufficient cash for change is in the drawer
  function enoughFund(cid) {
    var sum = cid.filter((el, i) => change >= currency[i]);
    return sum.reduce((a, b) => {
      return a + b[1];
    }, 0);
  }

  //Actual program/control flow starts here
  if (enoughFund(cid) < change)
    return "Insufficient Funds";
  else if (enoughFund(cid) === change)
    return "Closed";
  else {
    for (var i = cid.length - 1; i > -1; i--) {
      value = 0;
      while (cid[i][1] > 0 && change >= currency[i]) {
        //update everything as long as condition is true
        change -= currency[i];
        cid[i][1] -= currency[i];
        //value keeps track of the amount of each currency unit as change
        value += currency[i];
      }
      if (value)
        changeRecord.push([cid[i][0], value]);
    }
  }
  //divide each array by 100 to display a proper money format
  changeRecord.forEach(el => el[1] = (el[1] / 100));
  return changeRecord;
}

#2

Does it pass all the conditions?
I think there is a addition condition within insufficient fund that if there is not enough denomination to give out.

Return 50 cents, but only have $1.00 and $0.01.


#3

Yes, it passes all tests.

Sorry I’m not sure what you mean. Can you elaborate on what troubles you?


#4

Nothing troubles me, if it all pass them don’t worry about it :slight_smile:


#5

@pennyJack my only recommendation is to use proper ES6 variable syntax (const and let). Also, (this is more of a personal syntax preference), but in your if statements when you’re only returning one line of code I like to keep it on the same line as the conditional block so:

if (enoughFund(cid) < change) return "Insufficient Funds";
else if (enoughFund(cid) === change) return "Closed";
else {
    ...
}

Good job none the less!


#6

Very nice. Now can you explain it. What is this doing?


#7

I’ve seen const and let many times now, but since you have to prioritize somehow what to learn first (since there is sooo much to learn) I haven’t gotten much into the details of ES6 yet but will sure do later and then come back again and refactor.

Well, you’re right it does look cleaner. Simple but effective!

Thx! :slight_smile:


#8

Sure! First, it filters all arrays out of ‘cid’ that doesn’t meet the condition ‘change >=currency[i]’. In other words, only those arrays of ‘cid’ are stored in the new variable ‘sum’, whose respective “currency unit” reflection is below ‘change’. Then you just sum them all up. With this is simple to check beforehand if you have enough change in the drawer.

Simple example:

Imagine you have the following array: var cid = [[“PENNY”, 0.01], [“NICKEL”, 2.05], [“DIME”, 1.00], [“QUARTER”, 0.75], [“ONE”, 1.00], [“FIVE”, 0], [“TEN”, 0], [“TWENTY”, 0], [“ONE HUNDRED”, 0]]); and change equals 0.5.

After ‘enoughFund(cid)’ has run, ‘sum’ is equal to: sum = [[“PENNY”, 0.01], [“NICKEL”, 2.05], [“DIME”, 1.00], [“QUARTER”, 0.75]]. If you sum it up you get an amount > 0.5 which means there is enough cash in the drawer to give you back your change and the actual program can run.

Hope that makes things clearer! :slight_smile:


#9

I am still getting used to the fat arrow functional style. How have el and i.
el is the element (which is not used?) and i is the index so you can reference the currency array? That is what I am not sure about.


#10

Yes, that’s correct. You can name the arguments you pass to the callback whatever you want. I just called them el (like element) and i (for index). It’s more or less a shortcut for the regular callback syntax, where you can also pass different arguments (like for .filter() in this case). This article might help to get your head around.


#11

So you are not using el because you are really interested in accessing the index value i?