Для массива с пятью значениями:
let names = ["Bob", "Brian", "Jen", "Sarah", "Joe"]
let number = 3
Я хотел бы пройти через массив и удалить третье значение (используя числовую переменную, в этом примере это будет Jen
, а затем продолжить подсчет, чтобы следующий элемент, который нужно удалить, был бы Bob
. является третьим значением AFTER Jen
, когда цикл начинается в начале после того, как он превышает длину массива. Я хочу продолжить цикл таким образом, пока в массиве останется только один элемент.
Чтобы сделать это более визуально, результаты будут выглядеть так для каждой итерации:
Это проблема Иосифа. Я проверил это, используя входной тестовый пример из Rosetta Code, и он проходит, но мне было бы любопытно посмотреть, как он работает на дополнительном вводе, поскольку он кажется подозрительно менее подробным, чем все примеры кода на RC.
let names = ["Bob", "Brian", "Jen", "Sarah", "Joe"];
let number = 3;
for (let n = (number % names.length) - 1; names.length > 1;) {
names.splice(n, 1);
n = (n + number - 1) % names.length;
}
console.log(names);
Вот фрагмент запуска теста RC:
// https://rosettacode.org/wiki/Josephus_problem
// n=41 k=3
// killed: 2 5 8 11 14 17 20 23 26 29 32 35 38 0 4 9 13 18 22 27 31 36 40 6 12 19 25 33 39 7 16 28 37 10 24 1 21 3 34 15
// survived: 30
const killed = "2 5 8 11 14 17 20 23 26 29 32 35 38 0 4 9 13 18 22 27 31 36 40 6 12 19 25 33 39 7 16 28 37 10 24 1 21 3 34 15".split(" ");
const survived = "30";
let k = 3;
const prisoners = [];
const killSequence = [];
for (let i = 0; i < 41;) { prisoners.push(""+i++); }
for (let n = (k % prisoners.length) - 1; prisoners.length > 1;) {
killSequence.push(prisoners[n]);
prisoners.splice(n, 1);
n = (n + k - 1) % prisoners.length;
}
if (JSON.stringify(killSequence) === JSON.stringify(killed) && survived === prisoners[0]) {
console.log('Test passed. Survivor is ${prisoners[0]}.');
}
else {
console.log("Test failed");
}
i
, names[i]
и names.length
прямо перед splice
и вы увидите, что индекс будет за пределами определенной точки.
--len
дает неправильный ответ. Что вы предлагаете?
Предыстория: Флавий Иосиф Флавий был римским историком еврейского происхождения. Во время еврейско-римских войн первого века нашей эры он был в пещере с другими солдатами, всего 41 человек, в окружении вражеских римских войск. Они решили покончить жизнь самоубийством, вставая на ринг и подсчитывая каждого третьего человека. Каждый человек, которого так назначили, должен был совершить самоубийство. (Когда граф вернулся вокруг кольца, солдаты, которые уже совершили самоубийство, были пропущены в подсчете.) Иосиф Флавий, не желая умирать, занял позицию № 31, которая была последней позицией, которую нужно выбрать. В общей версии проблемы есть n солдат, пронумерованных от 1 до n, и каждый k-й солдат будет ликвидирован. Граф начинается с первого солдата.
Результат содержит массив, в котором элементы будут удалены. Ваш ответ будет последним элементом.
function josephus(array, count) {
// Return store
const store = [];
// Counter for each time the element should be spliced
let counter = 0;
// Array index position
let index = 0;
while (array.length > 0) {
// This is because 'array' is treated like a circular array
index = index % array.length;
if (++counter === count) {
// Remove the element from the array and push onto the store.
// The first element is used, hence [0]
store.push(array.splice(index, 1)[0]);
// Reset the counter
counter = 0;
// Move back one index value
index--;
}
index++;
}
return store;
}
// Example
console.log(josephus(["Bob", "Brian", "Jen", "Sarah", "Joe"], 3));
store
и вернуть его, чтобы получить желаемый конечный результат, но вы все равно не рассчитали результат, используя алгоритм, который он запрашивал
%
), чтобы получить индекс после конца массива ...