Как удалить элемент в массиве каждые X раз, пока длина массива не станет равной 1

1

Для массива с пятью значениями:

let names = ["Bob", "Brian", "Jen", "Sarah", "Joe"]
let number = 3

Я хотел бы пройти через массив и удалить третье значение (используя числовую переменную, в этом примере это будет Jen, а затем продолжить подсчет, чтобы следующий элемент, который нужно удалить, был бы Bob. является третьим значением AFTER Jen, когда цикл начинается в начале после того, как он превышает длину массива. Я хочу продолжить цикл таким образом, пока в массиве останется только один элемент.

Чтобы сделать это более визуально, результаты будут выглядеть так для каждой итерации:

  • боб
  • Брайан
  • ~~ Джен ~~
  • Сара
  • Джо

  • ~~ ~~ Боб
  • Брайан
  • ~~ Джен ~~
  • Сара
  • Джо

  • ~~ ~~ Боб
  • Брайан
  • ~~ Джен ~~
  • Сара
  • ~~ Джо ~~

  • ~~ ~~ Боб
  • ~~ ~~ Brian
  • ~~ Джен ~~
  • Сара
  • ~~ Джо ~~
  • 1
    Сложение и модуль ваши друзья.
  • 1
    Я бы предложил попробовать разбить проблему на части. Подсказка: вы можете использовать оператор модуля ( % ), чтобы получить индекс после конца массива ...
Показать ещё 3 комментария
Теги:
arrays
loops

2 ответа

2
Лучший ответ

Это проблема Иосифа. Я проверил это, используя входной тестовый пример из 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");
}
  • 0
    Зарегистрируйте i , names[i] и names.length прямо перед splice и вы увидите, что индекс будет за пределами определенной точки.
  • 0
    Интересно, что это не влияет на результат. --len дает неправильный ответ. Что вы предлагаете?
Показать ещё 12 комментариев
0

Предыстория: Флавий Иосиф Флавий был римским историком еврейского происхождения. Во время еврейско-римских войн первого века нашей эры он был в пещере с другими солдатами, всего 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));
  • 0
    Это не отвечает на его вопрос. Вы можете взять последний индекс массива вашего store и вернуть его, чтобы получить желаемый конечный результат, но вы все равно не рассчитали результат, используя алгоритм, который он запрашивал
  • 0
    На самом деле он делает то же самое, что и он, и я мог бы вернуть даже последний элемент, OP может сделать это сам, дополнительный бит для сообщества, которое хочет посмотреть, как это делается.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню