对于CodeWars上的这个Kata Level 6问题,9个测试中的 8 已通过。奇怪的是:CodeWars不会告诉我哪个测试用例失败了。
这是我的代码。也许这里有人可以提供帮助?非常感谢你。
function tickets(peopleInLine) {
var totalChange = 0;
for (var i = 0; i < peopleInLine.length; i++) {
if (peopleInLine[i] === 25) totalChange += 25;
if (peopleInLine[i] > 25) {
var change = peopleInLine[i] - 25;
if (totalChange < change) return "NO";
if (totalChange >= change) totalChange -= change;
}
}
return "YES";
}
这是问题:
新的&#34;复仇者&#34;电影刚刚发布!电影票房中有很多人站在一条巨大的线上。他们每人都有100,50或25美元的账单。 A&#34;复仇者&#34;门票费25美元。
Vasya目前是一名职员。他想向这一行中的每个人出售一张票。
瓦西亚可以向每个人出售一张票,如果他最初没有钱就给出改变,并严格按照人们在线下的顺序出售门票吗?
返回是,如果Vasya可以向每个人出售门票并进行更改。否则返回否。
示例:
tickets([25, 25, 50]) // => YES
tickets([25, 100]) // => NO. Vasya will not have enough money to give change to 100 dollars
答案 0 :(得分:3)
你需要计算你拥有的每张账单:如果有人给你100,你就不能只用一百张账单给他75。 tickets([25,25,25, 100,100])
应该返回"NO"
这是一个天真的解决方案,
function tickets(peopleInLine) {
//var totalChange = 0; not needed
var total25bill = 0;
var total50bill = 0;
var total100bill = 0;
for (var i = 0; i < peopleInLine.length; i++) {
//totalChange += peopleInLine[i]
if (peopleInLine[i] === 25) {
total25bill += 1;
} else if (peopleInLine[i] === 50) {
if (total25bill >= 1) {
total25bill =-1; //gives back 1 25$ bill
total50bill += 1;
} else {
return "NO";
}
} else if (peopleInLine[i] === 100) {
if ((total50bill >= 1) && (total25bill >= 1)){
total25bill =-1; //gives back 1 25$ bill
total50bill =-1; //gives back 1 50$ bill
total100bill += 1;
} else if (total25bill >= 3){
total25bill =-3; //gives back 3 25$ bill
total100bill += 1;
} else {
return "NO";
}
}
}
return "YES";
}
答案 1 :(得分:1)
Walle指出,您必须跟踪每张账单。下面是一个递归定义,它有3个状态变量a
,b
和c
,一个用于跟踪每种账单类型。
function isEmpty(xs) { return xs.length === 0; }
function first(xs) { return xs[0]; }
function rest(xs) { return xs.slice(1); }
function tickets(xs) {
function loop(a,b,c,xs) {
// validate drawer, a=$25, b=$50, c=$100
if (a < 0 || b < 0 || c < 0)
return "NO";
// if the drawer is valid and the line of people is empty...
else if (isEmpty(xs))
return "YES";
// otherwise, process the next person in line
else
switch (first(xs)) {
case 25:
return loop(a+1, b, c, rest(xs)); // give back $0
case 50:
return loop(a-1, b+1, c, rest(xs)); // give back $25
case 100:
return b > 0 // if drawer has a $50..
? loop(a-1, b-1, c+1, rest(xs)) // give back $25 + $50
: loop(a-3, b, c+1, rest(xs)) // give back 3 * $25
;
}
}
// start the loop with 0 of each bill in the drawer
return loop(0,0,0,xs);
}
我喜欢这个函数,因为没有重复的逻辑,并且循环中每个分支只有一个合理的返回值。
我也喜欢案例分析看起来像是每种账单类型的交易。
// in the case of someone paying with a $50
// give 1 a
// gain 1 b
// c stays the same
return loop(a-1, b+1, c, rest(xs))
这种状态变化使得很容易推断出程序的行为。
最简单的情况,1人,25美元
tickets([25])
=> 'YES'
1人,50美元。给他的没有变化:(
tickets([50])
//=> 'NO'
1人,100美元。此人也没有变化
tickets([100])
//=> 'NO'
2个人,首先是25美元。 50美元的第二个人获得25美元的变化
tickets([25,50])
//=> 'YES'
3个人首先是25美元。第二个人获得了第一个人25美元的变化。我们不能为抽屉里只有50美元的第三人做出改变。
tickets([25,50,100])
//=> 'NO'
与上述情况相同,但在我们处理100美元的账单之前还有25美元。这次我们有足够的变化。
tickets([25,50,25,100])
//=> 'YES'
如果3美元25美元在100美元的账单之前出现,也会有效,因为3 * 25美元(75美元)是100美元的有效变更。
tickets([25,25,25,100])
//=> 'YES'