双倍可乐挑战,JavaScript密码错误?
Double Cola Challenge, JavaScript code wrong?
五个朋友在排队喝魔法可乐。当第一个朋友喝了可乐,他就消失了,并且繁殖成两份!在那之后,那些新的副本到行尾,下一个朋友喝魔法可乐,重复这个过程。
例如,假设我们有以下朋友:
[Sheldon, Leonard, Penny, Rajesh, Howard]
Sheldon 喝完第一口可乐后,该行将如下所示:
[Leonard, Penny, Rajesh, Howard, Sheldon, Sheldon]
伦纳德喝完可乐后,台词变成了这样:
[Penny, Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard]
等等...
我的objective是在JavaScript中写了一个函数,给定一个数组,其中包含行中的人的名字,以及一个数字N,它将return第N个喝魔法可乐的人的名字。
所以,例如,做 console.log(whoIsNext([Sheldon, Leonard, Penny, Rajesh, Howard], 1))
应该 return 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, 1), "Sheldon");
但是测试失败:
names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 52), "Penny");
如果我尝试使用非常大的数字,例如:
names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 7230702951), "Leonard");
它甚至不会停止 运行(永远)。
很明显,我的解决方案不仅不正确,而且似乎也很低效。我该如何解决?
一个基于零的递归提议,其中 returns 数组的索引,这里的长度为 base = 5
。
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3
number 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
index 0 1 2 3 4 0 0 1 1 2 2 3 3 4 4 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 0 0 0 0 0
It become visible, the pattern is based on 5 and goes up for every round by factor 2.
5 -> 10- > 20 -> 40
Example of calculation
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;
function getIndex(n, i) {
i = i || base;
if (n < i) {
return Math.floor(n * base / i);
}
return getIndex(n - i, 2 * i);
}
var i = 0, index;
document.write(friends[getIndex(1 - 1)] + '<br>'); // "Sheldon"
document.write(friends[getIndex(52 - 1)] + '<br>'); // "Penny"
document.write(friends[getIndex(7230702951 - 1)] + '<hr>'); // "Leonard"
for (i = 0; i < 200; i++) {
index = getIndex(i);
document.write(i + ': ' + index + ' ' + friends[index] + '<br>');
}
好的,我们开始吧,这是一个非常简单的方法,我会想出一个更好的方法(我已经想了一半,我只需要将它放在一起)
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++;
}
}
这个想法是,每次人们完成一个完整的循环时,同一个人来的数量就会翻倍 (countPerson = Math.pow(2, countFullLoops)
)。如果再累积到设定指标之前的人数,直到达到指标,就找到合适的人了(我感觉我只是解释了一个很简单的事情真的很难)。
您也可以根据需要替换任何输入(更改开始时的人数,更改乘数(有人说四重可乐吗?))。
五个朋友在排队喝魔法可乐。当第一个朋友喝了可乐,他就消失了,并且繁殖成两份!在那之后,那些新的副本到行尾,下一个朋友喝魔法可乐,重复这个过程。
例如,假设我们有以下朋友:
[Sheldon, Leonard, Penny, Rajesh, Howard]
Sheldon 喝完第一口可乐后,该行将如下所示:
[Leonard, Penny, Rajesh, Howard, Sheldon, Sheldon]
伦纳德喝完可乐后,台词变成了这样:
[Penny, Rajesh, Howard, Sheldon, Sheldon, Leonard, Leonard]
等等...
我的objective是在JavaScript中写了一个函数,给定一个数组,其中包含行中的人的名字,以及一个数字N,它将return第N个喝魔法可乐的人的名字。
所以,例如,做 console.log(whoIsNext([Sheldon, Leonard, Penny, Rajesh, Howard], 1))
应该 return 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, 1), "Sheldon");
但是测试失败:
names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 52), "Penny");
如果我尝试使用非常大的数字,例如:
names = ["Sheldon", "Leonard", "Penny", "Rajesh", "Howard"];
Test.assertEquals(whoIsNext(names, 7230702951), "Leonard");
它甚至不会停止 运行(永远)。
很明显,我的解决方案不仅不正确,而且似乎也很低效。我该如何解决?
一个基于零的递归提议,其中 returns 数组的索引,这里的长度为 base = 5
。
1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 number 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 index 0 1 2 3 4 0 0 1 1 2 2 3 3 4 4 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 4 4 4 4 0 0 0 0 0
It become visible, the pattern is based on 5 and goes up for every round by factor 2.
5 -> 10- > 20 -> 40
Example of calculation
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;
function getIndex(n, i) {
i = i || base;
if (n < i) {
return Math.floor(n * base / i);
}
return getIndex(n - i, 2 * i);
}
var i = 0, index;
document.write(friends[getIndex(1 - 1)] + '<br>'); // "Sheldon"
document.write(friends[getIndex(52 - 1)] + '<br>'); // "Penny"
document.write(friends[getIndex(7230702951 - 1)] + '<hr>'); // "Leonard"
for (i = 0; i < 200; i++) {
index = getIndex(i);
document.write(i + ': ' + index + ' ' + friends[index] + '<br>');
}
好的,我们开始吧,这是一个非常简单的方法,我会想出一个更好的方法(我已经想了一半,我只需要将它放在一起)
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++;
}
}
这个想法是,每次人们完成一个完整的循环时,同一个人来的数量就会翻倍 (countPerson = Math.pow(2, countFullLoops)
)。如果再累积到设定指标之前的人数,直到达到指标,就找到合适的人了(我感觉我只是解释了一个很简单的事情真的很难)。
您也可以根据需要替换任何输入(更改开始时的人数,更改乘数(有人说四重可乐吗?))。