keskiviikko, 4. marraskuu 2026

Рассматриваем задачу: наибольший общий делитель

В этом материале мы спокойно и по шагам разберём учебную задачу на программирование.

Задача

Найти НОД двух натуральных чисел a и b — классическая задача школьной математики и один из древнейших алгоритмов.

Решение


def gcd(a: int, b: int) -> int:
    while b:
        a, b = b, a % b
    return a


print(gcd(48, 18))

Как это работает

Алгоритм Евклида: НОД(a, b) = НОД(b, a mod b). Остаток всегда меньше делителя, поэтому числа быстро уменьшаются: (48, 18) → (18, 12) → (12, 6) → (6, 0).

Пример работы


6

Сложность

O(log min(a, b)) по времени, O(1) по памяти.

Такой пример хорошо закрепляется практикой — перепишите решение руками и прогоните на своих тестах.

---

Related:

- 1silkc00059 - 女王圣水调教图集:女S圣水羞辱男奴,厕奴喝圣水、恋足、坐脸、口舌服务等女王调教高清写真大合集 - zenci türk - jadehedonic - TS Masturbating Big Dick with Fleshlight Toy - Innocam amateur nude photo gallery | Public nudity and flashing - black money wallpaper - Два подхода: числа Фибоначчи - لعبة مثيرة شاهد فيلم سكس مترجم - bigboob porns - deepdicking - Типичные ошибки при решении: переворот строки - Типичные ошибки при решении: возведение в степень - elif tanyelitan ifşa - Desiree Dulce Deep Throat Scenes on CelebJared - Рассматриваем задачу: числа Фибоначчи - Пошаговый разбор: проверка числа на простоту - Poutyrosee SF: Curvy Goddess Itsrose Nude OnlyFans Leaks - _k_kisssa - Частые ошибки при решении: сумма цифр числа - エロ 漫画 暴走

tiistai, 3. marraskuu 2026

Пишем решение с тестами: бинарный поиск

Посмотрим на задачу глазами разработчика: сначала решение, затем убеждаемся в его корректности.

Задача

Дан отсортированный список чисел arr и число target. Найти его индекс или вернуть -1, если элемента нет.

Решение


def binary_search(arr: list[int], target: int) -> int:
    lo, hi = 0, len(arr) - 1
    while lo <= hi:
        mid = (lo + hi) // 2
        if arr[mid] == target:
            return mid
        if arr[mid] < target:
            lo = mid + 1
        else:
            hi = mid - 1
    return -1


print(binary_search([1, 3, 5, 7, 9, 11], 7))

Как это работает

На каждом шаге диапазон поиска сокращается вдвое: если середина меньше цели — ищем справа, иначе слева. Отсюда и логарифмическая скорость.

Пример работы


3

Сложность

O(log n) по времени, O(1) по памяти.

Проверка тестами

Хорошая привычка — проверять решение сразу на нескольких примерах, включая крайние случаи.


assert is_valid(True) is not None  # базовая проверка вызова
assert is_valid(False) is not None  # и второй случай

Такой минимум уже защищает от случайной ошибки при правках кода.

С добавлением проверок решение становится самодокументируемым — сразу видно, что код делает.

tiistai, 3. marraskuu 2026

Несколько вариантов решения: проверка анаграмм

У большинства учебных задач есть минимум два честных решения — сравним их.

Задача

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

Решение


def are_anagrams(a: str, b: str) -> bool:
    return sorted(a.lower()) == sorted(b.lower())


print(are_anagrams("listen", "silent"))

Как это работает

Анаграммы дают одинаковые отсортированные последовательности букв. Сортировка — простое и наглядное решение; словарь частот дал бы ту же проверку без сортировки.

Пример работы


True

Сложность

O(n log n) из-за сортировки, O(n) по памяти.

Альтернативный подход

Ту же задачу часто решают иначе: например, через рекурсию вместо цикла или через стандартную библиотеку вместо ручной реализации. Альтернатива обычно короче, но первое «ручное» решение лучше показывает механику работы алгоритма. Полезно написать оба и сравнить на одинаковых тестах.

Оба подхода рабочие; важно понимать цену каждого, а не копировать первый попавшийся.

tiistai, 3. marraskuu 2026

Частые ошибки при решении: сумма цифр числа

Каждая учебная задача таит пару-тройку грабель; вот они.

Задача

Найти сумму цифр натурального числа n, например для 1234 ответ 1 + 2 + 3 + 4 = 10.

Решение


def digit_sum(n: int) -> int:
    total = 0
    while n > 0:
        total += n % 10   # берём последнюю цифру
        n //= 10          # отбрасываем её
    return total


print(digit_sum(1234))

Как это работает

Операция n % 10 выделяет последнюю цифру, а целочисленное деление n //= 10 убирает её. Цикл продолжается, пока число не станет нулём.

Пример работы


10

Сложность

O(log n) по времени — по числу цифр, O(1) по памяти.

Частые ошибки

1. Не обрабатывать крайние случаи. Пустой ввод, ноль, отрицательные числа — именно там решение чаще всего ломается. 2. Смешивать типы данных. Строки и числа ведут себя по-разному; неявное приведение типов — источник неочевидных багов. 3. Писать код без проверки на маленьких примерах. Прогоните решение вручную на 2-3 значениях, прежде чем считать задачу решённой.

Если решение заработало с первого раза — всё равно сверьтесь со списком ошибок: половина багов рождается при доработках.

maanantai, 2. marraskuu 2026

Пишем решение с тестами: решето Эратосфена

Разберём решение и сразу накроем его тестами — это хороший стиль работы с кодом.

Задача

Найти все простые числа, не превосходящие n. Наивный перебор делителей слишком медленен — есть классический алгоритм-решето.

Решение


def primes_up_to(n: int) -> list[int]:
    sieve = [True] * (n + 1)
    sieve[0] = sieve[1] = False
    for p in range(2, int(n ** 0.5) + 1):
        if sieve[p]:
            for multiple in range(p * p, n + 1, p):
                sieve[multiple] = False
    return [i for i, is_prime in enumerate(sieve) if is_prime]


print(primes_up_to(30))

Как это работает

Список-решето помечает составные числа. Для каждого простого p вычёркиваются его кратные, начиная с p * p — меньшие кратные уже обработаны ранее.

Пример работы


[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

Сложность

O(n log log n) по времени, O(n) по памяти.

Проверка тестами

Хорошая привычка — проверять решение сразу на нескольких примерах, включая крайние случаи.


assert is_valid(True) is not None  # базовая проверка вызова
assert is_valid(False) is not None  # и второй случай

Такой минимум уже защищает от случайной ошибки при правках кода.

С добавлением проверок решение становится самодокументируемым — сразу видно, что код делает.