Попробуй решить эти 5 задач на Python

Эти задачи прокачают твоё логическое мышление, внимание к деталям и помогут взглянуть на язык под новым углом. Вместо стандартных примеров вроде «разверни строку» или «посчитай сумму массива» – задачи, которые действительно интересно решать.

Разберём пять уровней сложности:

• Две задачи лёгкого уровня – потребуют внимательности и знания базового синтаксиса Python.

• Две задачи среднего уровня – помогут закрепить работу со структурами данных и алгоритмами.

• Одна сложная задача – вызов для тех, кто хочет испытать себя.

Готов? Тогда приступим!

Задача 1: Кто украл конфеты? (Лёгкий уровень)

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

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

find_thief("Анна Борис Виктор Анна Глеб") # → "Анна" find_thief("Сергей Павел Иван Ольга Павел") # → "Павел"

Задача 2: Числовая лестница (Лёгкий уровень)

Нужно сгенерировать пирамиду чисел. На i-й строке должно быть i чисел, каждое равно номеру строки.

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

generate_stairs(5)

Вывод:

1 2 2 3 3 3 4 4 4 4 5 5 5 5 5

Задача 3: Секретный пароль (Средний уровень)

У тебя есть список пользователей и их паролей. Нужно найти все пароли, которые содержат не менее 3 цифр.

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

passwords = ["qwerty123", "hello", "pass1", "secure9876", "abc"] find_strong_passwords(passwords) # → ["qwerty123", "secure9876"]

Задача 4: Самый длинный подотрезок (Средний уровень)

Дан список целых чисел. Нужно найти самый длинный подотрезок (непрерывную подпоследовательность), в котором все элементы различны.

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

longest_unique_subarray([1, 2, 3, 1, 2, 3, 4, 5]) # → [1, 2, 3, 4, 5]
longest_unique_subarray([5, 1, 3, 5, 2, 3, 4, 1]) # → [1, 3, 5, 2]

Эта задача полезна для понимания работы со словарами и указателями в алгоритмах.

Задача 5: Оптимальный маршрут курьера (Сложный уровень)

У курьера есть несколько точек доставки. Он должен пройти по всем точкам и вернуться в начальную, выбрав кратчайший путь. Дано n точек с координатами (x, y). Нужно найти оптимальный маршрут.

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

points = [(0, 0), (2, 3), (5, 5), (6, 2)] shortest_delivery_route(points)

Возможный оптимальный путь:

(0,0) → (2,3) → (5,5) → (6,2) → (0,0)

Задача сложная, так как относится к NP-трудным проблемам. Реализация наивного перебора всех вариантов невозможна при большом числе точек, поэтому придётся использовать жадные алгоритмы или приближённые методы.

Решения и разбор задач

Давайте разберём каждую задачу и возможные подходы к их решению.

Задача 1: Кто украл конфеты?

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

Решение:

def find_thief(names: str) -> str: name_count = {} for name in names.split(): if name in name_count: return name # Если имя уже встречалось, это вор name_count[name] = 1 return ""

Функция проходит по списку имен и использует словарь для отслеживания встреченных значений. Как только обнаруживается повторение — имя сразу возвращается.

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

• Использование set(), который не позволяет проверять порядок появления имен.

• Попытка сортировки списка перед поиском, что делает решение менее эффективным.

Задача 2: Числовая лестница

Построение лестницы чисел можно реализовать с помощью генерации строк.

Решение:

def generate_stairs(n: int) -> None: for i in range(1, n + 1): print(" ".join([str(i)] * i))

Функция использует списковое включение для создания строк, а join() превращает список чисел в текст.

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

• Использование print(i * i), что ведёт к математическим вычислениям вместо генерации строк.

• Пропуск пробелов между числами при формировании строки.

Задача 3: Секретный пароль

Здесь можно использовать регулярные выражения или цикл для подсчёта цифр в строке.

Решение через цикл:

def find_strong_passwords(passwords: list) -> list: return [pwd for pwd in passwords if sum(c.isdigit() for c in pwd) >= 3]

Эта функция проверяет количество цифр в каждом пароле, используя генераторное выражение внутри sum().

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

• Проверка только первой цифры if any(c.isdigit() for c in pwd), что даёт неверные результаты.

• Использование len(re.findall("\d", pwd)), что делает код менее читаемым.

Задача 4: Самый длинный подотрезок

Оптимальное решение использует два указателя (left и right) и set для отслеживания уникальных чисел.

Решение:

def longest_unique_subarray(arr): seen = set() left = 0 max_len = 0 best_subarray = [] for right in range(len(arr)): while arr[right] in seen: seen.remove(arr[left]) left += 1 seen.add(arr[right]) if right - left + 1 > max_len: max_len = right - left + 1 best_subarray = arr[left:right + 1] return best_subarray

Алгоритм работы:

1. left и right обозначают границы текущего подотрезка.

2. Пока right встречает повторяющееся число, двигаем left и удаляем элементы из множества.

3. При каждом обновлении границ проверяем, стал ли подотрезок длиннее предыдущего.

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

• Попытка сортировки массива, что ломает порядок элементов.

• Использование Counter() из collections, что замедляет выполнение.

Задача 5: Оптимальный маршрут курьера

Эта задача известна как задача коммивояжёра. Оптимальное точное решение — метод перебора всех возможных маршрутов, но он неэффективен для больших n. Используем жадный алгоритм (выбираем ближайшую точку на каждом шаге).

Решение:

from itertools import permutations def distance(p1, p2): return ((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2) ** 0.5 def shortest_delivery_route(points): start = points[0] min_route = None min_dist = float("inf") for perm in permutations(points[1:]): route = [start] + list(perm) + [start] dist = sum(distance(route[i], route[i+1]) for i in range(len(route) - 1)) if dist < min_dist: min_dist = dist min_route = route return min_route, min_dist

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

1. Используем permutations() для генерации всех возможных маршрутов.

2. Вычисляем расстояние каждого маршрута.

3. Выбираем маршрут с минимальной суммой расстояний.

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

• Неправильное вычисление расстояния: не abs(x1 - x2) + abs(y1 - y2), а евклидова метрика.

• Отсутствие возврата в начальную точку, что делает маршрут некорректным.

Мы разобрали 5 интересных задач разного уровня сложности. Простые задачи помогли закрепить основы работы со строками и списками, а сложные — познакомили с алгоритмами оптимизации.

Что можно сделать дальше?

• Попробовать написать более оптимальные версии решений.

• Реализовать задачи без встроенных функций Python.

• Решать аналогичные задачи на платформах LeetCode, Codewars, Stepik.

Практика — лучший способ прокачать навыки программирования. Начни с этих задач и попробуй придумать свои! 🚀

Начать дискуссию