Это условие задачи на FreeCodeCamp ( https://www.freecodecamp.org/learn/javascript-algorithms-and-data-structures/javascript-algorithms-and-data-structures-projects/cash-register )
Напишите функцию ящика checkCashRegister() которая принимает цену покупки в качестве первого аргумента ( price ), платеж как второй аргумент ( cash ) и денежный ящик ( cid ) в качестве третьего аргумента. cid - это 2D-массив, в котором доступна доступная валюта. Функция checkCashRegister() всегда должна возвращать объект со status ключом change . Return {status: "INSUFFICIENT_FUNDS", change: []} если сумма в ящике меньше, чем требуемое изменение, или если вы не можете вернуть точное изменение. Return {status: "CLOSED", change: [...]} с наличным ящиком в качестве значения для change ключа, если оно равно требуемому изменению. В противном случае верните {status: "OPEN", change: [...]} , с внесением изменений в монеты и счета, отсортированные в порядке наивысшего и наименьшего, в качестве значения ключа change . Не забудьте использовать Read-Search-Ask, если вы застряли. Попробуйте подключить программу. Напишите свой собственный код. Валютная единица Количество пенс 0,01 долл. США (PENNY) никель $ 0,05 (NICKEL) дайм $ 0.1 (DIME) четверть 0,25 долл. США (КВАРТАЛ) доллар $ 1 (ДОЛЛАР) Пять долларов $ 5 (ПЯТЬ) Десять долларов 10 долларов США (TEN) Двадцать долларов 20 долларов США (ДВАДЦАТЬ) Одна сотня долларов 100 долларов США (ОДНА СТО)
function checkCashRegister(price, cash, cid) {
//объявил переменную для сдачи
let change = cash - price;
//объявил переменную результата в виде пустого массива
let result = [];
//объявил переменную для содержания перечня наименований валюты и значения
let data={"ONE HUNDRED":100,"TWENTY":20,"TEN":10,"FIVE":5,"ONE":1,"QUARTER":0.25,"DIME":0.1,"NICKEL":0.05,"PENNY":0.01};
}
// Example cash-in-drawer array:
// [["PENNY", 1.01],
// ["NICKEL", 2.05],
// ["DIME", 3.1],
// ["QUARTER", 4.25],
// ["ONE", 90],
// ["FIVE", 55],
// ["TEN", 20],
// ["TWENTY", 60],
// ["ONE HUNDRED", 100]]
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]]);
Ниже идет правельное решение , взятое из подсказок
// Create an array of objects which hold the denominations and their values
var denom = [
{ name: "ONE HUNDRED", val: 100.0 },
{ name: "TWENTY", val: 20.0 },
{ name: "TEN", val: 10.0 },
{ name: "FIVE", val: 5.0 },
{ name: "ONE", val: 1.0 },
{ name: "QUARTER", val: 0.25 },
{ name: "DIME", val: 0.1 },
{ name: "NICKEL", val: 0.05 },
{ name: "PENNY", val: 0.01 }
];
function checkCashRegister(price, cash, cid) {
var output = { status: null, change: [] };
var change = cash - price;
// Transform CID array into drawer object
var register = cid.reduce(
function(acc, curr) {
acc.total += curr[1];
acc[curr[0]] = curr[1];
return acc;
},
{ total: 0 }
);
// Handle exact change
if (register.total === change) {
output.status = "CLOSED";
output.change = cid;
return output;
}
// Handle obvious insufficient funds
if (register.total < change) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
// Loop through the denomination array
var change_arr = denom.reduce(function(acc, curr) {
var value = 0;
// While there is still money of this type in the drawer
// And while the denomination is larger than the change remaining
while (register[curr.name] > 0 && change >= curr.val) {
change -= curr.val;
register[curr.name] -= curr.val;
value += curr.val;
// Round change to the nearest hundreth deals with precision errors
change = Math.round(change * 100) / 100;
}
// Add this denomination to the output only if any was used.
if (value > 0) {
acc.push([curr.name, value]);
}
return acc; // Return the current change_arr
}, []); // Initial value of empty array for reduce
// If there are no elements in change_arr or we have leftover change, return
// the string "Insufficient Funds"
if (change_arr.length < 1 || change > 0) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
// Here is your change, ma'am.
output.status = "OPEN";
output.change = change_arr;
return output;
}
// test here
checkCashRegister(19.5, 20.0, [
["PENNY", 1.01],
["NICKEL", 2.05],
["DIME", 3.1],
["QUARTER", 4.25],
["ONE", 90.0],
["FIVE", 55.0],
["TEN", 20.0],
["TWENTY", 60.0],
["ONE HUNDRED", 100.0]
]);
Сразу приношу прощение, если что-то не так сделал, я новичек и готов исправиться , если подскажите. Теперь проблема . Не могу понять логику кода (укажу по-руски что именно не понтятно, через коментарии в коде
// Handle exact change
if (register.total === change) {
output.status = "CLOSED";
output.change = cid;
return output;
}
// Handle obvious insufficient funds (почему иммено так ?register.total <
change )
if (register.total < change) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
// Loop through the denomination array
var change_arr = denom.reduce(function(acc, curr) {
var value = 0;
// While there is still money of this type in the drawer
// And while the denomination is larger than the change remaining
// этот момент не понятен с while,
while (register[curr.name] > 0 && change >= curr.val) {
change -= curr.val;
register[curr.name] -= curr.val;
value += curr.val;
// Round change to the nearest hundreth deals with precision errors
change = Math.round(change * 100) / 100;
}
// Add this denomination to the output only if any was used.
if (value > 0) {
acc.push([curr.name, value]);
}
return acc; // Return the current change_arr
}, []); // Initial value of empty array for reduce
// If there are no elements in change_arr or we have leftover change, return
// the string "Insufficient Funds"
// И этот момент не поянтен
if (change_arr.length < 1 || change > 0) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
// Here is your change, ma'am.
output.status = "OPEN";
output.change = change_arr;
return output;
}
Если кто-то умеет по сторочно объяснять, что происходит в коде, помогите пожалуйста .
1) Считаем сколько всего денег в кассе
var register = cid.reduce(
function(acc, curr) {
acc.total += curr[1];
acc[curr[0]] = curr[1];
return acc;
},
{ total: 0 }
);
2) Если денег в кассе всего точно равно сумме сдачи (т.е. в сдачу отдаем всю кассу) и выходим
if (register.total === change) {
output.status = "CLOSED";
output.change = cid;
return output;
}
3) Если в кассе всего денег меньше чем нужно дать сдачу то говорим что не хвататает средств и выходим
if (register.total < change) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
4) Основная часть алгоритма: логика простая, до тех пор пока 1) не насобирали сдачу ИЛИ 2) пока не перебрали все ячейки кассы ТО ДЕЛАЕМ следующее перебираем все ячейки кассы и собираем купюры/монеты от большего номинала к меньшему, берем номинал если он больше чем сдача то переходим к след меньшему номиналу, если номинал равен или меньше, то берем его добавляем в массив сдачи и вычитаем этот номинал из оставшейся сдачи и так далее
// Loop through the denomination array
var change_arr = denom.reduce(function(acc, curr) {
var value = 0;
// While there is still money of this type in the drawer
// And while the denomination is larger than the change remaining
while (register[curr.name] > 0 && change >= curr.val) {
change -= curr.val;
register[curr.name] -= curr.val;
value += curr.val;
// Round change to the nearest hundreth deals with precision errors
change = Math.round(change * 100) / 100;
}
// Add this denomination to the output only if any was used.
if (value > 0) {
acc.push([curr.name, value]);
}
return acc; // Return the current change_arr
}, []); // Initial value of empty array for reduce
5) если после 4) сдача еще осталась то говорим не хватает средств и выходим
if (change_arr.length < 1 || change > 0) {
output.status = "INSUFFICIENT_FUNDS";
return output;
}
6) Мэм вот ваша сдача
// Here is your change, ma'am.
output.status = "OPEN";
output.change = change_arr;
return output;
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Как настроить автодополнение таким образом, чтобы добавлялось не только имя функции, но и скобки после него?