Мысли вслух, когда я пытаюсь решить ката на Codewars

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

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

Чрезвычайно важно сделать шаг назад, провести повторную калибровку и прояснить ситуацию. Хотя сама тема может быть сложной и подавляющей, признать эту истину обнадеживает: любую проблему, которая кажется сложной, можно разбить на мельчайшие и простейшие части.

Я всегда предлагаю следующую диковинную аналогию: если вы можете дать четкие, краткие и точные указания, как направить кого-то, начиная с Луны (точка А), чтобы в конечном итоге пройти мимо вашего дома (точка Б) и оказаться в вашем местном кинотеатре (точка C), то у вас есть основа для решения проблем разработки программного обеспечения.

Это звучит как сложная задача, так что сейчас, вероятно, самое время немного ее разобрать.

Нам нужно задать себе несколько вопросов. Чего мы хотим достичь? Какие инструменты у нас есть для выполнения задачи? Кто может нам помочь? Куда мы идем и когда нам нужно быть в определенном месте? Есть ли определенный порядок, которому мы должны следовать? Почему мы делаем это в первую очередь? Связано ли это с чем-то, что я делал раньше? Сколько у нас права на ошибку? Какие проблемы могут возникнуть?

Пройдя стадию мозгового штурма, мы можем найти хороший план. Для всех намерений и целей, следующее решение может быть вариантом… нюансы в сторону, конечно. Нам нужно использовать космический шаттл или другой вид транспорта, чтобы отправиться с Луны и прибыть в дом, который расположен на определенной широте и долготе. Мы должны разделять и властвовать, поэтому лучший пилот должен быть в кресле пилота, а лучший штурман должен быть рядом с пилотом. Остальные члены команды также должны разделить оставшиеся роли и посмотреть, как они вписываются в план. Убедившись, что все меры предосторожности приняты, мы должны стремиться приземлиться рядом или в определенных координатах.

Как только мы волшебным образом добираемся до дома в целости и сохранности, нам нужно ехать либо на автобусе, либо на метро, ​​либо на машине до местного кинотеатра. Поскольку мы знаем, что некоторые дороги находятся в стадии строительства, и учли, какие улицы, как правило, более загружены, чем другие улицы, мы знаем кратчайший возможный путь… учитывая все обстоятельства. Если что-то случится неожиданно, мы также знаем, что существуют альтернативные маршруты. Нам также удобно пробовать новые маршруты, которые имеют смысл, даже если мы никогда не ездили по ним раньше. Несмотря ни на что, мы добираемся из точки А в точку Б самым логичным и разумным способом, какой только можем придумать.

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

Если мы сможем организованно добраться из точки А в точку Z, то мы сможем это сделать.

8kyu — Найдите максимальное и минимальное значения списка

Вот ссылка на задачу: https://www.codewars.com/kata/find-maximum-and-minimum-values-of-a-list

Круто, это звучит так, как будто мы можем сделать это на бумаге. Это приветственный знак. Приступим к делу.

  1. Хорошо, я прочитал название задачи. У меня есть представление о том, чего ожидать, но мне нужно прочитать описание, чтобы полностью понять задачу.
  2. Что опять просит? Пришло время прочитать его снова, сверху вниз и построчно, чтобы убедиться, что я нахожусь на той же странице, что и подсказка.
  3. Слова помогают, но они могут только зайти так далеко. Давайте подробнее рассмотрим эти примеры и посмотрим на ожидания в действии.
  4. Хорошо, теперь время для некоторых размышлений. Знаю ли я, что такое определение минимальной стоимости? Знаю ли я, что такое определение максимального значения? Я знаю, что такое список? Если я не знаю, что это такое, могу ли я собрать контекстные подсказки? Понятны ли мне примеры? Я не хочу упустить важную деталь, поэтому позвольте мне записать эту информацию.
  5. После заселения пришло время присмотреться. Какой тип данных получит функция? Это массив. Какие типы данных будет содержать массив? Это будут целые числа. Вкратце, какие соответствующие методы массива я знаю или знаю? Вкратце, какие соответствующие целочисленные методы я знаю или знаю? Будут ли возникать крайние случаи (исключительные ситуации)?
  6. Давайте обсудим некоторые подходы либо на бумаге, либо вслух. Пора посмотреть, куда заведут меня мои инстинкты. Я могу использовать встроенную функцию JavaScript Math.min(), а также другую встроенную функцию JavaScript Math.max(). Если я не знаком с этими методами, я могу найти их в документации Mozilla Developer Network (источник, который включает инструкции о том, как правильно использовать функции JavaScript). Поскольку эти методы могут быть связаны вместе с Function.prototype.apply() для обработки массива, мне нужно будет сделать что-то вроде Math.min.apply(null, arr), а также Math.max.apply. (нулевой, обр.). Я взял то, что я знаю о математической библиотеке JavaScript, и объединил это с тем, что я знаю о методе apply(), чтобы это произошло, что пришло из предыдущего опыта работы с ними по отдельности и вместе.
  7. Я хочу сделать это немного по-другому, потому что может быть больше пользы в том, чтобы быть как можно более явным. Как бы я выполнил задачу, используя только ручку и бумагу? Могу ли я вручную продемонстрировать это, водя пером и выполняя каждую итерацию вручную? Давайте сделаем это, а затем попробуем воспроизвести это с помощью кода.
  8. Вместо того, чтобы позволить встроенным методам выполнять всю работу, я хотел бы рассмотреть возможность использования двух вещей: цикла для прохода по массиву и переменной для хранения текущего минимума, который может меняться по мере прохождения массива. Какова цель, опять же? Эти два инструмента помогают ответить на вопрос: «Как я могу проверить каждое число и убедиться, что оно самое низкое из всех?»
  9. Я определю переменную с именем currentMin. CurrentMin должен начинаться со значения первого элемента массива. Под этим объявлением переменной я напишу цикл. Когда я перебираю массив, я сравниваю currentMin с текущим элементом в массиве. Если текущий элемент в массиве меньше значения currentMin, то пора переназначить currentMin на значение текущего элемента. Другими словами, если наш currentMin начинается с 4, и мы натыкаемся на целое число в массиве, такое как 2, мы должны сделать так, чтобы currentMin теперь был равен 2. К тому времени, когда мы пройдем весь массив, мы знать, что currentMin является фактическим минимумом, и тогда мы можем вернуть его.
  10. Та же логика может быть применена для нахождения максимального значения с одним небольшим изменением. Если текущий элемент в массиве больше, чем значение currentMax (которое было установлено равным первому элементу массива), то пришло время повторно присвоить currentMax значению текущего элемента. . Затем мы можем вернуть его после того, как цикл прекратит работу.
  11. Время перейти к этапу кодирования и тестирования!

Неаннотированная версия

function min(list) {
  let currentMin = list[0];
  
  for (let i = 0; i < list.length; i++) {
    let num = list[i];
    if (num < currentMin) currentMin = num;
  }  
  
  return currentMin;
}
function max(list) {
  let currentMax = list[0];
  
  for (let i = 0; i < list.length; i++) {
    let num = list[i];
    if (num > currentMax) currentMax = num;
  }
  
  return currentMax;
}

Аннотированная версия

function min(list) {
  let currentMin = list[0]; // initialize the currentMin variable with the value of the first element of the array;
  
  for (let i = 0; i < list.length; i++) { // go through each and every element of the array one by one;
    let num = list[i]; // assign the value positioned at a certain index to a more semantic variable name;
    if (num < currentMin) currentMin = num; // if the current integer is less than the value of currentMin, re-assign accordingly;
  }
  
  return currentMin; // return the current minimum, which may or may not have gone through many re-assignments;
}
function max(list) { // apply similar logic for this function;
  let currentMax = list[0];
  
  for (let i = 0; i < list.length; i++) {
    let num = list[i];
    if (num > currentMax) currentMax = num;
  }
  
  return currentMax;
}

Независимо от того, является ли проблема 8кю или 4кю, общая нить связывает все вместе. Задавайте себе вопросы. Что у нас есть? Куда мы идем? Что нам нужно, чтобы добраться туда? Что-то будет мешать нам? Определите, каковы самые маленькие и простые части проблемы. Имеет ли этот шаг смысл сам по себе и по отношению к следующему шагу? Запишите вещи вниз. Объясняйте вещи вслух. Попробуйте вещи. Не стесняйтесь экспериментировать. Если что-то пойдет не так, как планировалось, выздоравливайте. Поверните, если необходимо. Попробуй снова. Используйте опыт как рычаг. Доверьтесь своему чувству направления и своей выдержке.

Удачного кодирования!