На сегодня я подготовил челлендж HackerRank. Это испытание оценено как Средняя сложность, и это хорошо, мы продвигаемся: D. Посмотрим, что нам нужно делать!

Игровой массив

Энди любит играть в игры. Он хочет сыграть в игру со своим младшим братом Бобом, используя массив A различных целых чисел. Правила следующие:

1. Боб всегда играет первым, и два игрока ходят поочередно.

2. За один ход игрок выбирает максимальный элемент, присутствующий в данный момент в массиве, и удаляет его, а также все остальные элементы справа от него. Например, если A = [2, 3, 5, 4, 1], то после первого хода он становится A = [2, 3], потому что мы удаляем максимальный элемент (т. Е. 5) и все элементы справа от него (т. Е. 4 и 1).

3. Модификации, внесенные в массив во время каждого хода, являются постоянными, поэтому следующий игрок продолжает игру с оставшимся массивом. Первый игрок, который не может сделать ход, проигрывает.

Можете ли вы найти и вернуть имя победителя по исходному массиву? Если Энди выиграет, верните ANDY; если выиграет Боб, верните BOB.

Прежде чем читать дальше, я настоятельно рекомендую вам попробовать решить эту проблему самостоятельно, так вы извлечете из нее максимум пользы.

Обратите внимание, что я не утверждаю, что у меня есть лучшее решение для этой задачи, поэтому, если вы найдете лучшее, я хотел бы увидеть, как вы это сделали! :)

ОК… поехали!

Сначала я собираюсь написать функцию, которая будет иметь в качестве параметра массив A с различными целыми числами и будет возвращать winner в виде строки. Мы изначально устанавливаем winner как пустую строку.

function gamingArray(A){
    let winner = '';

    return winner;
}

Хорошо! А теперь посмотрим… Игра продолжается до тех пор, пока массив не останется пустым, верно? Это когда один из двух игроков проигрывает. Итак, нам нужно запускать цикл до тех пор, пока в массиве есть элементы:

function gamingArray(A){
    let winner = '';
    while(A.length){
    }
    return winner;
}

Мы также могли бы написать: while(A.length > 0), но в JavaScript 0 оценивается как false, поэтому мы сохраняем там некоторые символы xD.

Потрясающий! Теперь, когда у нас есть игровой цикл, для каждой итерации нам нужно играть в игру, верно? Итак ... нам нужно найти максимальное значение в массиве и удалить его вместе со всеми элементами справа.

Мы собираемся немного «сойти с ума» и проделать все эти шаги в одну строчку. Это то, что мне очень нравится в JavaScript!

Для этого нам понадобятся четыре вещи:

  1. Array.splice() = ›удаляет элементы из массива. Мы используем splice вместо slice, потому что это изменяет исходный массив.
  2. Array.indexOf() = ›ищет в массиве указанный элемент и возвращает его позицию.
  3. Math.max() = ›возвращает число с наибольшим значением.

4. Синтаксис распространения = ›позволяет раскрывать выражение в тех местах, где используются несколько аргументов (для вызовов функций), несколько элементов (для литералов массива) или несколько переменных (для деструктурирующего присваивания). ожидал. Подробнее об этом на MDN.

Используя синтаксис распространения в методе Math.max(), мы очень легко получаем максимальное значение из массива без необходимости перебирать все числа. Это сделает это за нас.

Давайте посмотрим, как все эти части идеально сочетаются друг с другом:

function gamingArray(A){
    let winner = '';
    while(A.length){
        A.splice(A.indexOf(Math.max(...A)));
    }
    return winner;
}

Так элегантно! Я люблю это! ❤

Давайте теперь посмотрим, сколько ходов они сыграли в игре, пока массив не опустеет. Для этого я собираюсь добавить переменную turns, инициализированную с помощью 0, которая будет увеличиваться на 1 в каждом цикле. Вы поймете, зачем нам это нужно.

function gamingArray(A){
    let winner = '';
    let turns = 0;
    while(A.length){
        A.splice(A.indexOf(Math.max(...A)));
        turns++;
    }
    return winner;
}

Хорошо, но ... как мы узнаем, кто победил?

Это очень легко. Я объясню:

Предположим, у нас есть одно число в массиве. Мы знаем, что Боб всегда играет первым, поэтому он удаляет это число, и поэтому Энди проигрывает, потому что больше не осталось ходов, поэтому Боб выигрывает

Для двух чисел в порядке возрастания, например [1, 2], мы получим:

  1. Боб удаляет number2;
  2. Энди удаляет number1;
  3. Массив пуст… Побеждает Энди.

Для трех чисел в порядке возрастания, например [1, 2, 3]

  1. Боб удаляет 3;
  2. Энди удаляет 2;
  3. Боб удаляет 1;
  4. Массив пуст… Боб выигрывает.

Как видите, если у нас есть even количество ходов, выигрывает Боб, в противном случае выигрывает Энди. Здесь мы определим победителя с помощью переменной turns:

function gamingArray(A){
    let winner = '';
    let turns = 0;
    while(A.length){
        A.splice(A.indexOf(Math.max(...A)));
        turns++;
    }
    winner = (turns % 2 === 0) ? 'Andy' : 'Bob';
    return winner;
}

Мы используем тернарный оператор, чтобы определить победителя.

Давайте также вернем напрямую результат этой операции и избавимся от переменной winner:

function gamingArray(A){
    let turns = 0;
    while(A.length){
        A.splice(A.indexOf(Math.max(...A)));
        turns++;
    }
    return (turns % 2 === 0) ? 'Andy' : 'Bob';
}

Ура! Мы решили еще одну интересную задачу по программированию! : D

Вывод

Для меня это испытание было большим развлечением, потому что я должен был очень элегантно смешать все эти прекрасные методы JavaScript. ^ _ ^

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

Надеюсь, вам это понравилось, я искренне признателен, если вы нажмете кнопку Рекомендовать 💚. Спасибо!