День 1/30 дней CodeWars: JavaScript Edition

Решенные задачи CodeWars
1) Сумма положительных чисел (8 кю)
2) Считать овец (8 кю)
3) Держать обруч (8 кю)


Ката 1: Сумма положительных

Инструкции

Вы получаете массив чисел, верните сумму всех положительных чисел. Примечание: если нечего суммировать, сумма по умолчанию равна 0.

Примеры

[1,-4,7,12] => 1 + 7 + 12 = 20
[] => 0
Войти в полноэкранный режим Выход из полноэкранного режима

Решение проблемы с помощью P.R.E.P.

Параметры
Функция ожидает один параметр: массив чисел.

The given array of numbers can ...
1) be empty 
2) contain only positive numbers 
3) contain only negative numbers 
4) contain a combination of both 
Войти в полноэкранный режим Выйти из полноэкранного режима

Возвращает
Функция должна вернуть одно значение: число.

The function should return 0 if ...
1) the array is empty
2) the array only contains negative numbers
Войти в полноэкранный режим Выйти из полноэкранного режима
The function should return a positive number if 
there is at least 1 positive number inside the array
Войти в полноэкранный режим Выйти из полноэкранного режима

Примеры
Следующие тестовые примеры предоставлены CodeWars.

[1,2,3,4,5], 15
[1,-2,3,4,5], 13
[], 0
[-1,-2,-3,-4,-5],0
[-1,2,3,4,-5], 9
Вход в полноэкранный режим Выход из полноэкранного режима

Число, следующее за массивом, является значением/суммой, которое должно быть возвращено.

Псевдокод
Смотрите раздел псевдокода для каждого решения


Решение 1: Использование цикла for

Псевдокод

1) Declare a 'sum' variable.
2) Loop over the given array.
3) Check if the current number in the loop is positive.
4) If it is, add that number to the current value of 'sum'.
5) Return the 'sum' variable
Войдите в полноэкранный режим Выход из полноэкранного режима

Код JavaScript

function positiveSum(arr) {
  let sum = 0;
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] > 0) {
      sum += arr[i];
    }
  }
  return sum;
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Примечания

1) Переменная sum объявлена со значением по умолчанию 0, чтобы гарантировать, что она вернет 0, если массив пуст или не содержит положительных чисел.

2) Цикл начинается с индекса 0, а не 1 — как в массиве — и продолжается до тех пор, пока индекс цикла меньше длины массива, чтобы не возникало ошибок off-by-one.

3) Скобочная нотация — arr[1] — используется для выбора элемента в массиве по текущему индексу цикла (так, если цикл находится по индексу 0, то выбирается элемент в массиве по индексу 0, то есть первый элемент в массиве).

4) Оператор += является оператором присваивания сложения и сокращенно обозначает переменная = переменная + значение (в данном случае sum = sum + arr[i]).


Решение 2: Использование методов массивов filter() и reduce()

Псевдокод

1) Create a new array containing only positive numbers.
2) Loop over the new array.
3) Sum up all values in the new array.
4) Return the 'sum' variable.
Войдите в полноэкранный режим Выйти из полноэкранного режима

JavaScript-код

function positiveSum(arr) {
  return arr.filter(num => num > 0)                   
            .reduce((sum, curr) => sum + curr, 0);     
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Примечания

1) Методы filter() и reduce() используются для перебора массивов и получают в качестве параметра функцию обратного вызова.

2) Функция обратного вызова filter() проверяет каждый элемент на заданное условие (как оператор if в решении 1), и метод создает новый массив со всеми элементами, прошедшими проверку.

3) Метод reduce() возвращает одно значение. Функция обратного вызова определяет вычисление (например, сложение или вычитание) или действие (например, конкатенация) для каждого элемента, за которым следует начальное значение (в данном случае 0). На каждой итерации предыдущее (или начальное) значение этого вычисления/действия передается в текущую итерацию, пока не останется единственное значение.

4) Оба этих метода не вносят никаких изменений в исходный массив.


Это решение я представил для данной задачи. На мой взгляд, это элегантное решение, не требующее большого количества кода, но при этом гораздо более простое для чтения и понимания, чем следующее решение.


Решение 3: Использование только метода массива reduce()

Эта реализация объединяет подходы решения 1 и решения 2 в одной строке кода внутри функции, хотя в этой статье она была распределена на 2 строки, чтобы избежать горизонтальной полосы прокрутки в блоке кода ниже.

Код JavaScript

function positiveSum(arr) {
  return arr.reduce((sum, curr) => 
    curr > 0 ? sum + curr : sum, 0);  
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Примечания

1) Аналогично решению 1, мы перебираем все элементы заданного массива, только вместо цикла for используем метод массива reduce().

2) Оператор if из решения 1 заменяется условным троичным оператором для проверки, является ли число положительным. Если да, то он должен вернуть значение суммы и прибавить к нему текущее число. Если число не является положительным, оно должно просто вернуть значение суммы для данной итерации.


Ката 2: Счет овец

Инструкции

Рассмотрим массив/список овец, в котором некоторые овцы могут отсутствовать на своем месте. Нам нужна функция, которая подсчитывает количество овец, присутствующих в массиве (true означает присутствие).

Пример

[true,  true,  true,  false,
  true,  true,  true,  true ,
  true,  false, true,  false,
  true,  false, false, true ,
  true,  true,  true,  true ,
  false, false, true,  true]
Войти в полноэкранный режим Выйти из полноэкранного режима

Правильным ответом будет 17.

Подсказка: Не забывайте проверять плохие значения, такие как null/undefined.


Разбор проблемы с помощью P.R.E.P.

Параметры
Функция ожидает один параметр: массив значений.

The given array of numbers can ...
1) be empty 
2) contain only true values
3) contain only falsy values (like false, null, undefined)
4) contain a combination of both 
Войти в полноэкранный режим Выйти из полноэкранного режима

Возвращает
Функция должна вернуть одно значение: число.

The function should return 0 if ...
1) the array is empty
2) the array only contains falsy values
Войти в полноэкранный режим Выйти из полноэкранного режима
The function should return a positive number if 
there is at least 1 sheep present (true) inside the array
Войти в полноэкранный режим Выйти из полноэкранного режима

Примеры
Тестовый пример в этой задаче такой же, как и пример, приведенный в инструкции выше.

Псевдокод
Смотрите раздел псевдокода для каждого решения


Решение 1: Использование цикла for

Эта задача довольно похожа на задачу в ката 1 и имеет аналогичное решение, за исключением нескольких незначительных изменений.

Псевдокод

1) Declare a 'count' variable.
2) Loop over the given array.
3) Check if the current value in the loop is TRUE.
4) If it is, add 1 to the current value of 'count'.
5) Return the 'count' variable
Вход в полноэкранный режим Выход из полноэкранного режима

Код JavaScript

function countSheeps(arrayOfSheep) {
  let count = 0;
  for (let i = 0; i < arrayOfSheep.length; i++) {
    if (arrayOfSheep[i]) {
      count++;
    }
  }
  return count;
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Примечания

1) Часто новички в коде пишут if (condition === true), что по своей сути не является неправильным, но на самом деле лишнее. В этом случае arrayOfSheep[i] будет иметь значение true, если значение true (или истинное) и false, если значение ложное.

2) Оператор инкремента (++) используется для добавления 1 к нашему счетчику присутствующих овец.


Решение 2: Использование цикла forEach

Код из решения 1 можно сократить всего до 3 строк внутри функции, используя цикл forEach вместо цикла for и комбинируя его с условным тернарным оператором, описанным в решении 3 ката 1.

Код JavaScript

function countSheeps(arrayOfSheep) {
  let count = 0;
  arrayOfSheep.forEach(sheep => sheep ? count++ : count);
  return count;
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Примечания

1) Цикл forEach выполняет код, указанный в функции обратного вызова, для каждого элемента массива.

2) В отличие от методов массивов filter() и reduce(), метод массива forEach() возвращает undefined, если только в функции обратного вызова не будет явно возвращено что-либо.

3) Цикл forEach является отличной альтернативой циклу for при обращении к массиву. Он менее склонен к ошибкам off-by-one, поскольку просто перебирает каждый элемент массива, не определяя количество повторений, как это делается в цикле for.


Решение 3: Использование метода массива filter() и свойства length

Псевдокод

1) Create a new array containing only TRUE values.
2) Return the length of that array.
Вход в полноэкранный режим Выход из полноэкранного режима

Код JavaScript

function countSheeps(arrayOfSheep) {
  return arrayOfSheep.filter(sheep => sheep).length;
}
Вход в полноэкранный режим Выйти из полноэкранного режима

Примечания

1) Как и в ката 1, мы используем метод массива filter() для создания нового массива, на этот раз содержащего только значения овец, которые присутствуют в массиве.

2) Затем мы просто используем свойство length для подсчета количества значений во вновь созданном массиве.


Это решение я представил для этого ката. Оно состоит всего из 1 строки кода, но при этом легко читается и понимается.


Ката 3: Продолжайте крутить обруч

Инструкции

Алекс только что получил новый хула-хуп, он любит его, но чувствует себя удрученным, потому что его младший брат лучше него.

Напишите программу, в которой Алекс может ввести (n) количество оборотов обруча, и она выдаст ему ободряющее сообщение 🙂

  • Если Алекс наберет 10 или более обручей, вернется строка «Отлично, теперь переходим к трюкам».
  • Если он не набрал 10 обручей, верните строку «Продолжай, пока не получится».

Разбор проблемы с помощью P.R.E.P.

Параметры
Функция ожидает один параметр: число.

The number can be 0 or greater than 0, but should not be a
negative number.
Войти в полноэкранный режим Выйти из полноэкранного режима

Возвращает
Функция должна вернуть одно значение: строку (сообщение).

The function should return "Great, now move on to tricks" if
the number is greater than or equal to 10.
Войти в полноэкранный режим Выйти из полноэкранного режима
The function should return "Keep at it until you get it" if
the number is smaller than 10.
Войти в полноэкранный режим Выйти из полноэкранного режима

Примеры
Следующие тестовые примеры предоставлены CodeWars.

3 => "Keep at it until you get it" 
11 => "Great, now move on to tricks" 
Вход в полноэкранный режим Выход из полноэкранного режима

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


Решение 1: Использование оператора if/else

function hoopCount (n) {
  if (n >= 10) {
    return "Great, now move on to tricks";
  } else {
    return "Keep at it until you get it";
  }
}
Войти в полноэкранный режим Выйти из полноэкранного режима

Решение 2: Использование условного троичного оператора

function hoopCount (n) {
  return n >= 10 
    ? "Great, now move on to tricks" 
    : "Keep at it until you get it";
}
Вход в полноэкранный режим Выход из полноэкранного режима

Примечания

Нередко код внутри условных троичных операторов разбивается на несколько строк, как в приведенном выше блоке кода. Это улучшает читаемость, поскольку условие занимает одну строку, затем следует код, который должен быть выполнен, если он оценивается как true, и, наконец, код, который должен быть выполнен, если он оценивается как false.


Это решение я представил для этой задачи. Лично я большой поклонник троичных операторов. Я знаю, что некоторые люди считают их трудными для чтения, но для меня они часто легче, чем операторы if/else (если только у вас не много операторов и/или они не вложенные).


Решение 3: Добавление обработчиков ошибок

Первые два решения не выполняют никакого кода, если входные данные недействительны (отрицательное число или вообще не число). Это не было требованием для прохождения тестовых примеров в задаче, но было приятным дополнением.

function hoopCount (n) {
  if (n >= 10) {
    return "Great, now move on to tricks";
  } else if (n < 10 && n >= 0) {
    return "Keep at it until you get it";
  } else {
    return "Invalid input"
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Какое решение вы реализовали?
Какое решение показалось вам наиболее элегантным?
Какое решение вызвало у вас затруднения?

Дайте мне знать, я с удовольствием выслушаю вас!

Надеюсь, эта статья была вам полезна.


Подключайтесь ко мне на …
Twitter
GitHub

Оцените статью
Procodings.ru
Добавить комментарий