Программки 💻
September 30, 2021

📗 Литкод

моя любимая страничка на сайте

Начало пути

Этим летом на просторах ютьюба я наткнулся на плейлист с лекциями по алгоритмам от Яндекса. Лектор рассказывал о сложности, показывал несколько решений, и объяснял их. Плейлист этот был рассчитан на людей, которые хотят пойти на работу/стажировку в Яндекс. Не скрою, сам сидел на их сайте стажировок. Так вот на этой странице были требования к работнику. И, как я помню, аккаунт на литкоде/хакерранке был плюсом в резюме.

Так я и зарегистрировался. Тем более давно меня уже мучила проблема: я знал основы Golang, но мне не хватало практики для закрепления знаний. В итоге была поставлена цель: решать минимум по одной задачке в день. Конечно, в первые дни было непривычно: такие задачки я решал разве что на олимпиадах по информатике, и когда читал замечательную кингу "Теоретический минимум по computer science" Владстона Феррейра Фило. Но потом мне начало это дико нравиться.

Итак, задачки

Я начал почти по порядку - лёгкие алгоритмы, которые все знают. Мне очень понравился алгоритм Two Sum. После того как я его написал, решил даже почитать пару статей на эту тему. Также мне понравился блок с комментариями пользователей, где люди помогают друг другу, объясняют свои решения и ищут ошибки в ответах других.

Не помню точно, на какой задачке, но я решил завести репозиторий с решёнными тасками. Зачем? Большинство из этих алгоритмов весьма полезны в моих проектах (особенно myAtoi). Ну и гитхаб свой надо было оживлять, ведь за 2020-ый год у меня не было коммитов вообще😨.

тот самый репозиторий

Люблю эту опенсорсную эстетику гитхаба. Где каждый может предложить что-то уже существующему проекту. Найти баг, исправить его, и отправить владельцам продукта. Также возможность посмотреть исходный код - крутая опция (да я из тех, кто смотрит исходный код страницы).

Так вот, гитхаб

Создание репозитория с тасками заставило меня проводить больше времени на гитхабе. В профиле было около 4-5ти репозиториев, и меня это категорически не устраивало. Также я смотрел на аккаунты фронтенд девелоперов и фуллстак разработчиков, и завидовал: смайлики, картинки, статистика и пр. Ну а чем я хуже? Взял и сделал себе красивую страничку.

мой гитхаб на момент написания этого поста

Что-то я ушёл от темы Литкода

По моему мнению таски на литкоде нужно выполнять на С++. Чтобы код выполнялся быстрее. Для меня плюсы - язык чисто академический. Да, я учу его в университете, да на нём практически все объясняют ООП. Но на практике я использую С++ только как язык для написания скетчей Ардуино, и то, это уже не совсем плюсы. Но я выбрал golang. Не буду писать почему. Просто это мой любимый язык 😍.

Так нужно ли мне регистрироваться на литкоде?

Ну смотря чего ты хочешь. Если ты:

  • хочешь устроиться в ИТ-компанию
  • лучше узнать один из языков
  • улучшить свой технический английский
  • научиться оптимизировать код

то я бы порекомендовал создать тебе профиль на этом замечательном сайте.

А, да, раз уж я затронул тему английского. Да, весь сайт на английском языке. Не то, что бы очень техническом, но в крайнем случае у тебя есть переводчик.

По поводу оптимизации

После того, как ты выполнишь ту или иную таску, литкод измерит скорость твоего решения и затраты памяти, и покажет статистику, где можно посмотреть другие варианты решения этой задачи. И вот смотря решения с рантаймом 0, я понял как можно оптимизировать код. В играх такое называют "микроконтроль". Ну что же это я о таком рассказываю, и без примера 😅.

Есть два числа, записанные как string, написать функцию, которая возвращает их частное. Ничего сложного. Вот моё решение:

func multiply(num1 string, num2 string) string {
	if num1 == "0" {
		return "0"
	}
	if num2 == "0" {
		return "0"
	}

	rune1 := []rune(num1)
	rune2 := []rune(num2)
	t := make([]int, len(rune1)+len(rune2))

	for i := 0; i < len(rune1); i++ {
		for j := 0; j < len(rune2); j++ {
			t[i+j+1] += int(rune1[i]-'0') * int(rune2[j]-'0')
		}
	}
	for i := len(t) - 1; i > 0; i-- {
		t[i-1] += t[i] / 10
		t[i] = t[i] % 10
	}
	if t[0] == 0 {
		t = t[1:]
	}

	result := make([]rune, len(t))
	for i := 0; i < len(t); i++ {
		result[i] = '0' + rune(t[i])
	}

	return string(result)
}

Не буду вдаваться в подробности, прошу обратить внимание на if'ы в самом начале:

if num1 == "0" {
		return "0"
	}
if num2 == "0" {
		return "0"
	}

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

Но это решение - лучшее, что я смог придумать.

статистика этого таска

Да, я добился крайне быстрой работы алгоритма. Но с памятью не всё так хорошо. С другой стороны быстрый код, который ещё и память не использует - это уже верх мастерства, а я простой студент из России :^)

Итог

Пока не закончатся задачи или моё воображение, буду решать по таску в день. Как поступить тебе - сам решай. А на этом мой пост заканчивается. Thats all, thank you!