This one really pushed me to my limits. I had to take a break. I solved it, I think, in nearly a week. This is a really untidy one. Doing it day after day sometimes make me forget about the code, and had to re-skim the code, had to use debug techniques, and had to make comment lines to save me some time in understanding my own code.
I can’t think of more ways of tidying up the code, because I think their positioning mattered. Maybe you can?
You can ask for clarification if the comments were’nt enough. And, I would like to know ALL of your thoughts on my ‘messy’ approach.
It was fun and frustrating, Loved it FCC!
Thank you!
Solution
function checkCashRegister(price, cash, cid) {
// currency in the comment means penny, dime, nickel...
// initial variables
// cashSetChange - array of currency units that stores the change
// totalCash - sum of cash in drawer (cid)
cash*=1000;
price*=1000;
let currAmt=[10,50,100,250,1000,5000,10000,20000,100000];
let totalCash=0;
cid.forEach(item => totalCash+=item[1]*1000);
let change = cash-price;
let cashSetChange=[];
cid.forEach(item => item[1]*=1000);
let insufficientFunds = () => {
return {status:"INSUFFICIENT_FUNDS", change:[]};
}
let closed = () =>{
// replaces with change those currency that has 0 value in cid
for(let i in cashSetChange){
for (let x in cid){
if(cid[x][0] == cashSetChange[i][0]){
cid[x][1] = cashSetChange[i][1];
}
}
}
return {status:"CLOSED", change:cid};
}
let open = () => {
return {status:"OPEN", change:cashSetChange}
}
// obvious insufficient funds
if(totalCash < change){
return insufficientFunds();
}
// function for calculating the change: start checking from highest currency unit using amtIndex
// amtIndex - acts as the pointer of what currency (penny, dime...) is being evaluated in the function.
let intChange =0;
let calcChange = (amtIndex) => {
// TEST CODE- uncomment the line below for debug
// console.log("change: "+ change +" currAmt: "+currAmt[amtIndex]+ " cid: "+cid[amtIndex][1] +" amtIndex: " + amtIndex);
// the change needed is satisfied
if(change <= 0){ return "case_sufficient"; }
// move to lower currency only if currency is too much for change OR drawer has no cash for that specific currency
if(change < currAmt[amtIndex] || cid[amtIndex][1]<=0){
amtIndex--;
intChange=0;
}
// this has reached the lowest currency and theres not enough money for change
if(amtIndex < 0){ return "case_insufficient"; }
// if specific currency is enough for change AND has cash in drawer
if(change-currAmt[amtIndex] >= 0 && cid[amtIndex][1] > 0){
// subtract value of currency from change, from drawer, and totalCash
change -= currAmt[amtIndex];
totalCash -= currAmt[amtIndex];
cid[amtIndex][1] -= currAmt[amtIndex];
// accumulate the currency
intChange+= currAmt[amtIndex];
// save the changes to cashSetChange before it moves to next currency
if(change < currAmt[amtIndex] || cid[amtIndex][1]<=0){
cashSetChange.push([cid[amtIndex][0], intChange/1000]);
}
}
return calcChange(amtIndex);
}
let theCase = calcChange(currAmt.length-1);
let res = theCase == "case_insufficient" ? insufficientFunds() : totalCash <= 0? closed() : open();
// to see what is being returned
console.log(res);
return res;
}
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]]);