I’m so, so, so SORRY to do a code dump.
I spent a long time trying to complete this and I need to step away from the pc. That being said. At some point I would like to refactor and improve the code.
I know my code is shocking and I humbly ask you to help review my code and offer suggestions for improvement.
Current Solution
function checkCashRegister(price, cash, cid) {
debugger
let remaining = customRound(getRemaining(cash, price), 2)
remaining = multiplyByOneHundred(remaining)
let GLOBAL_COUNT = 0;
let currentCid = deepCloneArray(cid).reverse()
let fullCid = deepCloneArray(cid).reverse()
let changeGivenArray = []
while (remaining > 0) {
let check = checkSufficientFunds(remaining, currentCid)
if (check) {
let [bestValue, count] = getBestValue(remaining, currentCid, GLOBAL_COUNT)
GLOBAL_COUNT = count
currentCid = deepCloneArray(cid).reverse().slice(GLOBAL_COUNT)
let [r, subtracted] = subtractFromRemaining(remaining, currentCid, fullCid, GLOBAL_COUNT)
remaining = r
updateChangeGiven(changeGivenArray, bestValue, subtracted)
}
if (remaining == 0) {
return {
status: tillIsEmpty(fullCid) ? "CLOSED" : "OPEN",
change: tillIsEmpty(fullCid) ? cid : changeGivenArray
}
}
else {
continue
}
}
return {
status: "INSUFFICIENT_FUNDS",
change: []
}
function subtractFromRemaining(remaining, currentCid, fullCid) {
const proposedSubtraction = multiplyByOneHundred(currentCid[0][1])
const check = compareNum(proposedSubtraction, remaining)
const currencyDefault = currencyLookup(currentCid[0][0])
let subtracted;
console.log("currentCid: ", currentCid[0][0], "fullCid", fullCid[GLOBAL_COUNT][0])
const conditional = currentCid[0][0] == fullCid[GLOBAL_COUNT][0]
console.log("This is the conditional check value: ", conditional);
// if proposedSubtraction is greater than remaining
if (check) {
// https://stackoverflow.com/a/4228376/15592981
const quotient = Math.floor(remaining / currencyDefault)
subtracted = quotient * currencyDefault
currentCid[0][1] -= subtracted / 100
// will conditional always be true?
if (conditional) {
fullCid[0][1] -= subtracted / 100
}
}
else {
subtracted = multiplyByOneHundred(currentCid[0][1])
currentCid[0][1] = 0
if (conditional) {
fullCid[GLOBAL_COUNT][1] = 0;
}
}
remaining -= subtracted
return [remaining, subtracted]
}
function checkSufficientFunds(remaining, cid) {
// Iterate through cid to check if sufficient funds
// check which is best value later
// let cidDictionary = new Map();
let bool = false;
let currencyInTill = 0
for (let level of cid) {
currencyInTill += customRound(
multiplyByOneHundred(level[1]),
2
)
let currencyType = currencyLookup(level[0])
if (currencyType <= remaining && currencyInTill >= remaining) {
bool = true
break
}
}
// return everything after loop finishes
return bool
}
function getBestValue(remaining, currentCid, GLOBAL_COUNT) {
// Work needs to be done here <-----
// check which is best value. Iterate through cash in draw and check
// if currencyDefault is less than or equal to remaining
// if currencyInTill is greater than or equal to remaining
let bestChangeFound = false
let bestChangeValuePackage = undefined
let count = GLOBAL_COUNT
let currencyType;
let currencyInTill;
let check = checkSufficientFunds((remaining), currentCid)
for (let [type, inTill] of currentCid) {
currencyType = type
currencyInTill = multiplyByOneHundred(inTill)
let currencyDefault = currencyLookup(type)
if (check && bestChangeFound == false && currencyDefault <= remaining && inTill > 0) {
bestChangeFound = true
break
}
count++
}
if (bestChangeFound == true) {
bestChangeValuePackage = [currencyType, count]
}
return bestChangeValuePackage
}
}
function customRound(num, precision) {
const factor = Math.pow(10, precision);
return Math.round(num * factor) / factor;
}
function compareNum(x, y) {
// Can be used to check if cash is greater than price
// Can be used to check if current iteration of cid is greater than change needed
if (x > y) {
return true;
}
else {
return false;
}
}
function getRemaining(x, y) {
return x - y;
}
function multiplyByOneHundred(float) {
// convert float to number
return float * 100;
}
function currencyLookup(key) {
// returns int from object
const currencyObject = {
'PENNY': 1,
'NICKEL': 5,
'DIME': 10,
'QUARTER': 25,
'ONE': 100,
'FIVE': 500,
'TEN': 1000,
'TWENTY': 2000,
'ONE HUNDRED': 10000
}
return currencyObject[key]
}
function updateChangeGiven(arr, key, subtracted) {
arr.push([key, subtracted / 100])
}
/*
https://dev.to/samanthaming/how-to-deep-clone-an-array-in-javascript-3cig
Deep clone with recursion
Tareq Al-Zubaidi
*/
function deepCloneArray(arr) {
return arr.map(val => {
return Array.isArray(val) ? deepCloneArray(val) : val
})
}
function tillIsEmpty(cid) {
return cid.every(till => {
return till[1] == 0
})
}
// console.log(checkCashRegister(3.26, 100, [["PENNY", 1.01], ["NICKEL", 2.05], ["DIME", 3.1], ["QUARTER", 4.25], ["ONE", 90], ["FIVE", 55], ["TEN", 20], ["TWENTY", 60], ["ONE HUNDRED", 100]]))
console.log(checkCashRegister(19.5, 20, [["PENNY", 0.5], ["NICKEL", 0], ["DIME", 0], ["QUARTER", 0], ["ONE", 0], ["FIVE", 0], ["TEN", 0], ["TWENTY", 0], ["ONE HUNDRED", 0]]))