w3c 收银系统算法挑战
下面有写注释的! 找个钱好累呀~
function checkCashRegister(price, cash, cid) {
price = cash - price;
let arr = [0.01, 0.05, 0.10, 0.25, 1, 5, 10, 20, 100];
for (var k = 0; k < cid.length; k++) {
if (!(cid[k][1] - price)) {
return 'Closed';
}
}
let change = [];
let i = cid.length - 1;
while(i >= 0) {
if (!!cid[i][1] && price - arr[i] >= 0) {
let x = Math.min(price / arr[i], cid[i][1] / arr[i]);
x = parseInt(x);
change.push([cid[i][0], Number((arr[i] * x).toFixed(2))]);
price = +(price - arr[i] * x).toFixed(2);
if (price === 0) {
return change;
}
}
if (i === 0) {
return "Insufficient Funds";
}
i--;
}
}
function checkCashRegister(price, cash, cid) {
// 获取要找的钱 = 付款金额 - 购买价格
price = cash - price;
// 把美元面值的大小按照收银机顺序罗列
let arr = [0.01, 0.05, 0.10, 0.25, 1, 5, 10, 20, 100];
// 先判断是不是有正合适的钱,如果有那么直接找给客户就可以了
for (var k = 0; k < cid.length; k++) {
// 你要40我这里正好有2张20的
if (!(cid[k][1] - price)) {
return 'Closed';
}
}
// 如果没有正合适的钱,那就得凑一凑看看找不找的开
// change相当于手,捏着要找给客户各种面额的钱
let change = [];
// 把给的cid循环一遍,写成for循环可能更直观,但是我开始的想法不是这种,是用的while
let i = cid.length - 1;
while(i >= 0) {
// 如果二维数组的当前项的金额不是0,并且差额减去当前面值可以减得开,可以进判断语句(例如要找50块 - 20面值 = 2,那么可以进判断语句。如果要找19块 - 20面值 < 0,你要19块钱,我这是20块的票子,怎么可以给你,你再去看看10块面值的吧!)
if (!!cid[i][1] && price - arr[i] >= 0) {
// 获取一个金额的最小倍数, 如果取最大值,是不需要找这么多钱或者是没这么多钱去找的,所以去最小倍数,看看能给几张此面值的钱
let x = Math.min(price / arr[i], cid[i][1] / arr[i]);
// 如果我要找是50块钱,这个20面值的有5张,我只能找两张给客户,得到需要2.5张20面值的
// 2.5张不能撕了给你吧,要取个整给你两张对不对,如果是要找40,那就给两张就行了
x = parseInt(x);
// 把钱拿出来放手里
change.push([cid[i][0], Number((arr[i] * x).toFixed(2))]);
// 都给过你两张20块面值的钱了,那么看看还需要找给你多少钱,去下一个面值看看有没有
// 你需要
price = +(price - arr[i] * x).toFixed(2);
// 你需要50块钱,到这个10块面值了,正好给你一张就够了,应找金额成0了,不用继续往下找啦。
if (price === 0) {
// 把手里拿着的钱找给客户,找个钱这么麻烦!!
return change;
}
}
// 对8起,收银机里1分面值的钱都找完了还是找不开
if (i === 0) {
// 找给你个棒棒糖8 =_=
return "Insufficient Funds";
}
i--;
}
}