Путь в тысячу вёрст начинается с Hello World
На курсах по программированию периодически задают вопрос о задачах для закрепления навыков. Где взять эти задачи и как решить первую?
Существуют проекты посвященные практике решения задач по программированию — leetcode, codewars, egabit, coderun и другие. Задачи в подобных проектах ранжируются по уровню сложности, а свое решения можно проверять на тестах. Часто, задачи требуют знания алгоритмов, поэтому новичкам можно и нужно выбирать простые задачи.
Давайте начнём наш путь в тысячу вёрст с решения задачи проект leetcode -2667. Create Hello World Function, которая относится к простым задачам.
Часть задач leetcode (задачи там называются проблемами/problems) можно решать на Python, JavaScript/TypeScript или других языках. Эту задачу предлагается решить только на JS/TS. Она входит в серию задач названную «30 дней JavaScript». Даётся фрагмент кода:
/**
* @return {Function}
*/
var createHelloWorld = function() {
return function(...args) {
}
};
/**
* const f = createHelloWorld();
* f(); // "Hello World"
*/
и предлагается записать решение так, чтобы при вызове функции f() возвращалась строка «Hello, world».
В первом многострочном комментарии любезно подсказывается что функция createHelloWorld будет возвращать функцию. В JS это неудивительно — функция по сути особый объект, а объекты можно возвращать. Во втором комментарии приводится пример работы кода, т. е. то как он будет функционировать когда мы решим задачу.
rest-оператор с переменной args служат больше отвлекающим действием, нежели помогают решению.
Итак, всё что нам нужно, это прописать return «Hello, world» в возвращаемой функции.
var createHelloWorld = function() {
return function(...args) {
return "Hello World"
}
};
или через стрелочную
const createHelloWorld = () => () => "Hello World";
Этот код пройдёт тесты (они запускаются кнопкой Run) в верхней части страницы с задачей.
Когда мы прошли тесты, можно отправить свое решение кнопкой Submit. Это запускает проверку задачи на бОльшем количестве тестов. Отправка задачи учитывается и потом становится видна в виде записи в истории отправок. При успешном решении показывается график, на котором можно посмотреть с какой скоростью выполнилось ваше решение и решения других решающих.
В начале решения задач, скорость может не быть определяющим фактором. Но со временем (забавная игра слов) часть задач могут не пройти из-за длительности выполнения. К тому же появляется спортивный интерес — может ли мой код работать быстрей? Почему и как кто-то написал более быстрый код? Моя задача решена за 53 миллисекунды (это время показанное для решения выше), какой код у более быстрого решения за 21 ms?
На увиденном графике можно нажать самый левый столбец и подсмотреть быстрое решение. В текущем случае «более быстрое» решение на 21 ms выглядит так
function createHelloWorld() {
const greeting = "Hello World";
return function() {
return greeting;
};
}
Но при запуске этого решения как своего кода оно выдает время сопоставимое с начальным решением, из чего можно сделать предположение что первоначальное решение выглядит хорошим.
Нам этом можно было бы и остановиться. Но, решая задачи на JS, рано или поздно захочется посмотреть как выглядит решение задачи на TypeScript (TS). Во всех случаях, с которыми я сталкивался на текущий момент времени, решение отличается только добавкой базовых типов:
function createHelloWorld() {
return function(...args): string {
return "Hello World"
};
};
или по-хулигански:
function createHelloWorld() {
return function(...args): "Hello World" {
return "Hello World"
};
};
В TS есть понятие литеральных типов, когда типом начинает считаться конкретная строка (например, Hello World). В коде решения возвращаемая функция обещает возвращать не просто строки, а конкретную строку.
Первый шаг сделан, первая задача решена. Можно ли сформировать привычку ежедневного решения задач? Говорят, что на формирование привычки уходит 21 день. У каждого из нас есть возможность это проверить.