Ответ 1
При незначительном изменении индексов у вас есть проблема Джозефуса. В традиционной формулировке человек 1 убивает человека 2, 3 убивает 4 и т.д. Чтобы преобразовать в эту форму, убейте человека 1, как заявляет ваша проблема, а затем перенумеруйте людей 2-100 путем вычитания 1, давая людям 1-99.
Хорошее отношение к проблеме Иосифа Флавия, в том числе рассказ о его происхождении в еврейском восстании 70-73 года н.э., содержится в разделе "Бетонная математика", второе издание, глэм, Кнут и Паташник, раздел 1.3. В Wikipedia и Wolfram MathWorld есть статьи о проблеме, Wikipedia даже включает в себя оригинальное описание Иосифа Флавия в еврейской войне.
Книга дает слегка сложную рекурсию для решения и более простой алгоритм. Если число людей n
и n = 2^l + m
, где l
как можно больше, тогда ответ будет 2m+1
. Итак, поскольку 99 = 2^6 + 35
, решение 2*35 + 1 = 71
. Но вам нужно отменить перенумерацию, поэтому реальный ответ 72
.
Что касается вашей проблемы с программированием, почему бы вам не взять на себя основную операцию. Удалите первого человека в круге и переместите второго человека до конца. Итак, с 5
людьми, [1,2,3,4,5]
, вы удаляете первое получение [2,3,4,5]
и перемещаете новый первый элемент до конца, получая [3,4,5,2]
.
var killAndRotate = function(array) { // say [1,2,3,4,5]
var dead = array.shift(), // dead = 1, array = [2,3,4,5]
skipped = array.shift(); // skipped = 2, array = [3,4,5]
array.push(skipped); // array = [3,4,5,2]
}
И тогда основной цикл будет выглядеть следующим образом:
while (chairArray.length > 1) {
killAndRotate(chairArray);
}
alert(chairArray[0]); // or console.log, or return.
// In turn, array is:
// [1,2,3,4,5]
// [3,4,5,2]
// [5,2,4]
// [4,2]
// [2] and we alert, log, or return 2.
Добавлено
Легкий способ найти этот результат для исходной задачи Джозефуса - увидеть, что:
Если есть 2^l
люди, то в первом проходе все четные люди убиваются, поэтому первый человек остается в живых.
1 2 3 4 5 6 7 8
X X X X
Теперь есть 2^(l - 1)
люди. И снова выживает первый человек:
1 2 3 4 5 6 7 8
X X X X
X X
Повторите этот процесс; первый человек переживает каждый проход, а также последний выживший.
Теперь предположим, что есть m
дополнительные люди с m < 2^l
. Здесь l = 3
и m = 5
. Убейте первых m
людей, чтобы умереть.
1 2 3 4 5 6 7 8 9 10 11 12 13
X X X X X Y
Теперь осталось 2^l
человек, а человек 2 m + 1 = 11
- первый в строке. Так он выживает.
Следует также отметить, что добавление новой индексной переменной и сплайсинга может привести к ошибке программиста. Поскольку вам нужно только удалить с фронта и добавить обратно, используйте основные методы массивов.