На сегодня я подготовил челлендж 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!
Для этого нам понадобятся четыре вещи:
Array.splice()
= ›удаляет элементы из массива. Мы используемsplice
вместоslice
, потому что это изменяет исходный массив.Array.indexOf()
= ›ищет в массиве указанный элемент и возвращает его позицию.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]
, мы получим:
- Боб удаляет number
2
; - Энди удаляет number
1
; - Массив пуст… Побеждает Энди.
Для трех чисел в порядке возрастания, например [1, 2, 3]
…
- Боб удаляет
3
; - Энди удаляет
2
; - Боб удаляет
1
; - Массив пуст… Боб выигрывает.
Как видите, если у нас есть 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. ^ _ ^
У вас есть лучшее решение? Пожалуйста, не стесняйтесь сообщать мне об этом в разделе комментариев ниже. Я многому научился у людей, которые представили свое собственное решение предыдущих проблем кодирования, которые у нас были в прошлом. Узнайте о них подробнее здесь.
Надеюсь, вам это понравилось, я искренне признателен, если вы нажмете кнопку Рекомендовать 💚. Спасибо!