双重可乐挑战,JavaScript代码错误?

双重可乐挑战,JavaScript代码错误?,javascript,challenge-response,Javascript,Challenge Response,五个朋友在排队喝魔可乐。当第一个朋友喝可乐时,他消失了,并复制成两份!在那之后,这些新的拷贝到了队列的末尾,下一个朋友喝了魔可乐,重复这个过程 例如,假设我们有以下朋友: [Sheldon, Leonard, Penny, Rajesh, Howard] 谢尔顿喝下第一杯可乐后,队伍将如下所示: [Leonard, Penny, Rajesh, Howard, Sheldon, Sheldon] [Penny, Rajesh, Howard, Sheldon, Sheldon, Leonar

五个朋友在排队喝魔可乐。当第一个朋友喝可乐时,他消失了,并复制成两份!在那之后,这些新的拷贝到了队列的末尾,下一个朋友喝了魔可乐,重复这个过程

例如,假设我们有以下朋友:

[Sheldon, Leonard, Penny, Rajesh, Howard]
谢尔顿喝下第一杯可乐后,队伍将如下所示:

[Leonard, Penny, Rajesh, Howard, Sheldon, Sheldon]
[Penny, Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard]
莱纳德喝了可乐后,台词是这样的:

[Leonard, Penny, Rajesh, Howard, Sheldon, Sheldon]
[Penny, Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard]
等等

我的目标是用JavaScript编写一个函数,给定一个数组,其中包含行中的人的名字和一个数字N,它将返回第N个喝魔可乐的人的名字

例如,执行
console.log(whoIsNext([Sheldon,Leonard,Penny,Rajesh,Howard],1))
应该返回
Sheldon

为了实现这一点,我编写了以下代码:

function whoIsNext(names, r){
  var fistInLine;

  if(r <= names.length){
    return names[r-1];
  }else{

    while(r > names.length){
      fistInLine = names.shift();
      names.push(fistInLine, fistInLine);
    }
    return names[r-1];
  }
}
但它在测试中失败了:

names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 52), "Penny");
如果我尝试使用一个非常大的数字,比如:

names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 7230702951), "Leonard");
它甚至不会停止运行(需要永远)


所以很明显,我的解决方案不仅不正确,而且似乎也不完善。如何修复它?

一个基于零的递归建议,返回数组的索引,这里的长度
base=5

当它变为可见时,模式以5为基础,每轮上升2倍

5 -> 10- > 20 -> 40
计算示例

                Array after step
                0 1 2 3 4 5 6 7 8 9 
  0: 0 Sheldon  | 
  1: 1 Leonard  | |
  2: 2 Penny    | | |
  3: 3 Rajesh   | | | |
  4: 4 Howard   | | | | |
  5: 0 Sheldon    | | | | |
  6: 0 Sheldon    | | | | | |
  7: 1 Leonard      | | | | | |
  8: 1 Leonard      | | | | | | |
  9: 2 Penny          | | | | | |
 10: 2 Penny          | | | | | |
 11: 3 Rajesh           | | | | |
 12: 3 Rajesh           | | | | |
 13: 4 Howard             | | | |
 14: 4 Howard             | | | |
 15: 0 Sheldon              | | |
 16: 0 Sheldon              | | |
 17: 0 Sheldon                | |
 18: 0 Sheldon                | |
 19: 1 Leonard                  |
 20: 1 Leonard                  |
 21: 1 Leonard
 22: 1 Leonard
var-friends=['Sheldon','Leonard','Penny','Rajesh','Howard'],
base=friends.length;
函数getIndex(n,i){
i=i | |基;
if(n”);//“谢尔顿”
写(friends[getIndex(52-1)]+“
”);//“便士” 写(friends[getIndex(7230702951-1)]+“
”;//“伦纳德” 对于(i=0;i<200;i++){ index=getIndex(i); 写(i+':'+索引+''+朋友[索引]+'
);
}
好了,我们开始吧,这是一个非常简单的方法,我会想出一个更好的方法(我已经想了一半,我只需要把它组合起来)

函数whoIsNext(名称、索引、乘数)
{
var count=names.length;
var=0;
风险价值指数=0;
while(货币指数)
{
返回名称[i];
}
}
fullLoops++;
}
}
这个想法是,每次人们做一个完整的循环时,同一个人来的数量会翻倍(
countPerson=Math.pow(2,countFullLoops)
)。如果你在设定的索引之前累积人数,直到你达到索引,你就会找到合适的人(我觉得我只是解释了一件非常简单的事情,非常困难)


此外,您还可以根据需要替换任何输入(更改开始时的人数,更改乘法因子(有人说四倍可乐吗?)。

为什么要推两次?@epascarello,因为这不是一个简单的队列-从前面移除时,条目会在最后重复。这就是为什么它是一个更难的谜题。我错过了…咖啡还没有开始。为什么不采取数学方法呢?毕竟,每次通过每个人时,你总是附加两倍数量的名字。。。应该有一个清晰的模式可以识别,这可能是通过得到比你的支票号码低2倍的最高组合来计算的。从这里开始计算,直到得到一个介于0和4之间的数字,然后得到索引。应该不需要一直计算。目前在工作中,我将在大约。。。2小时或更长的时间,你的函数会考虑到一个事实,即名字是重复的,而其他名字不是重复的?此外,数组不会每轮大小增加一倍。我不明白它是怎么做到的。它只是上升了1个值。仔细想想,从队列中删除一个值,然后添加2个值。总偏移量为+1。其余的保持不变。因此,如果数组有5个名称,在第一次运行后,它将有6个,而不是10个@菲尼克斯,你在哪里看到10?啊,明白了!就是这样!
function whoIsNext(names, index, multiplyFactor)
{
    var count = names.length;

    var fullLoops = 0;
    var currIndex = 0;

    while(currIndex <= index)
    {
        for(var i = 0; i < count; i++)
    {
            currIndex += Math.pow(multiplyFactor, fullLoops);
            if(currIndex > index)
            {
            return names[i];
            }
        }
        fullLoops++;
    }
}