确定对于1行测试用例中的票证是否有足够的更改失败

时间:2016-05-30 17:56:01

标签: javascript for-loop functional-programming codewarrior

对于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

2 个答案:

答案 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个状态变量abc,一个用于跟踪每种账单类型。

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'