The real cash register algorithm

Warning: there may be spoilers in this post for those that are still working on cash register be forewarned.

The issue is that the free code camp register can pass the tests but it does not really work. I am not claiming to completely fix this but would like to try to play with it to see if it can pass some additional tests not solved with greed.

I looked up ‘Cash Register Greedy’ what came up was this but it did not go into much detail:
Greed

observe:

checkCashRegister(.70, 1, [["PENNY", 0], ["NICKEL", 0], ["DIME", .3], ["QUARTER", .25], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]])

returns “INSUFFICIENT FUNDS” which just not true,
it tries to take from the highest denomination that has a value and does not stop taking from that denomination unless the conditions are met.

I changed the last condition from :

if (moneyStillOwed != 0) {
status = "INSUFFICIENT_FUNDS";
change = [];
}

to be the following:

if ( moneyStillOwed != 0 && totalCid< moneyStillOwed){
  //now I will add if the money owed is not zero AND the total in drawer is less than moneyStillOwed
	status= "INSUFFICIENT_FUNDS";
	change=[]
  } else {
  cid= getCidObject()
  log('this is cid in miserly before the miserly loop: '+cid);
  
    let change=[]
  let status= "OPEN"
  for(let i=0; i<=cid.length-1; i++){

please see this codepen

My first question is why is cid not resetting itself by the getCidObject() i defined? since the greedy method has mutated this object, I would like to try to reset the object, discard everything I did , and then try again but instead of trying to pay off with the highest denomination, start off with the lowest and work your way up…

I realize that this still isnt going to work, as in some cases your going to take from the highest and then take from the lowest…
I.e. in a case where you owe .30 but your cid is

["NICKEL", 0.05], ["DIME", .3], ["QUARTER", .25]

than its ok to start from the highest pay off .25 and then start from .05 values, keeping the mutated cid and all your counts from greedy, and not resetting. and that the same case would not work if you just started from the lowest denomination.

but in a case where its

["NICKEL", 0.00], ["DIME", .3], ["QUARTER", .25]

you are going to have to reset all the greediness you did and revert cid back to its original state if you want to make an exact .30

Im sure there are many other situations and that a more comprehensive solution is something recursive that is going to be way beyond my current level of abilities to understand …

Ok now I see how to reset cid as miserlyCid and not pass a reference to the mutated cid which was mutated by greedy:

  let miserlyCid = [];

for (var i = 0; i < cid.length; i++){
    miserlyCid[i] = cid[i].slice();
}