Какие новые библиотеки изучаешь

Ответ

Ответ не найден

Ответ 18+ 🔞

Ах ты ж ёпта, ну и история у нас тут, про эти ваши... как их... охуительные алгоритмы! Слушай, вот представь: сидишь ты, такой, пишешь код, всё вроде красиво, а потом — бац! — и вылезает какая-нибудь дичь, от которой мозг вскипает, как чайник у бабки в деревне. Прям как в том анекдоте про программиста и чайник, только чайник — это твой собственный код, который ты только что написал и уже ненавидишь.

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

def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

Смотри, в чём прикол: чтобы посчитать fib(5), этой функции надо вызвать себя аж 15 раз! А для fib(30) — уже больше 2.5 миллионов вызовов! Это ж пиздец какой-то, а не алгоритм. Компьютер начнёт пыхтеть, как паровоз, а ты будешь сидеть и думать: «Ну че, ёпта, я же всё правильно написал, почему оно так долго?»

А всё потому, что функция тупо пересчитывает одни и те же значения по сто хуев раз. fib(3) считается и там, и сям, и ещё разок для прикола. Эффективность — ниже плинтуса, прямо как у мартышки с гранатой.

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

def fib_memo(n, memo={}):
    if n in memo:
        return memo[n]
    if n <= 1:
        return n
    memo[n] = fib_memo(n-1, memo) + fib_memo(n-2, memo)
    return memo[n]

Видишь? Добавили простой словарик memo. Прежде чем считать что-то с нуля, проверяем — а не считали ли мы это уже? Если считали — сразу отдаём результат, без всяких там танцев с бубном. Сложность с экспоненциальной превращается в линейную, O(n). Для fib(30) теперь нужно не миллионы вызовов, а всего лишь 59. Чувствуешь разницу? Как будто с говённого Запорожца пересел на нормальную тачку.

А можно вообще пойти дальше и сделать итеративное решение, без рекурсии. Типа «забудь про рекурсию, давай по-простому, как мужики».

def fib_iterative(n):
    if n == 0:
        return 0
    a, b = 0, 1
    for _ in range(1, n):
        a, b = b, a + b
    return b

Вот это уже вообще красота! Никаких лишних вызовов, память почти не жрёт, работает быстрее ветра. Просто берём и по порядку вычисляем числа, от первого до n-ного. Всё, ебушки-воробушки, задача решена эффективно и без лишней суеты.

Так что мораль, блядь, какая? Не всегда самое красивое и «математическое» решение — самое умное. Иногда надо просто подумать головой, а не жопу рвать рекурсией на ровном месте. Динамическое программирование — это как та самая заначка в тумбочке: когда припёрло, а у тебя уже всё готово. Главное — вовремя вспомнить, куда ты её, сука, спрятал.