Упражнения

A: Среднее значение

Напишите функцию average(a), которая получает на вход список чисел и возвращает среднее значение элементов данного списка. Список содержит только числа и не пуст.

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
average([1, 7, 9])
5.666666666666667

B: Медиана трех чисел

Напишите функцию median(a, b, c), которая получает на вход три числа и возвращает их медиану. В решении нельзя использовать циклы.

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
median(1, 9, 7)
7

C: Принадлежит ли точка квадрату - 1

Даны два действительных числа \(x\) и \(y\). Проверьте, принадлежит ли точка с координатами \((x,y)\) заштрихованному квадрату (включая его границу). На рисунке сетка проведена с шагом 1.

Решение оформите в виде функции is_point_in_square(x, y), возвращающую True, если точка принадлежит квадрату и False, если не принадлежит.

Функция is_point_in_square не должна содержать инструкцию if и должна иметь такой вид:

def is_point_in_square(x, y):
    return ...

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
is_point_in_square(0, 0)
True
is_point_in_square(3, -7)
False

D: Принадлежит ли точка квадрату - 2

Решите аналогичную задачу для такого квадрата:

Решение должно соответствовать требованиям для решения задачи C.

Функция должна называться is_point_in_rhombus.

Вызов функции Возвращаемое значение
is_point_in_rhombus(0, 0)
True
is_point_in_rhombus(1, 1)
False

E: Принадлежит ли точка кругу

Даны пять действительных чисел: \(x\), \(y\), \(x_c\), \(y_c\), \(r\). Проверьте, принадлежит ли точка \((x,y)\) кругу с центром \((x_c,y_c)\) и радиусом \(r\).

Решение оформите в виде функции is_point_in_circle(x, y, xc, yc, r).

Решение должно соответствовать требованиям для решения задачи C.

Вызов функции Возвращаемое значение
is_point_in_circle(0.5, 0.5, 0, 0, 1)
True
is_point_in_circle(0.5, 0.5, 1, 1, 0.1)
False

F: Принадлежит ли точка области

Проверьте, принадлежит ли точка данной закрашенной области. Область неограничена снизу.

Решение оформите в виде функции is_point_in_area(x, y).

Инструкцию if использовать по-прежнему нельзя.

Вызов функции Возвращаемое значение
is_point_in_area(-1, 2)
True
is_point_in_area(0, 0)
False

G: Разверните число

Дано число, получите число, составленное из тех же цифр, записанных в обратном порядке.

Решение оформите в виде функции reverse(n), которая получает на вход значение типа int и возвращает значение типа int.

Вызов функции Возвращаемое значение
reverse(179)
971

H: Следующий палиндром

Для данного числа \(n\) определите следующее за ним число, запись которого является палиндромом.

Решение оформите в виде функции next_palindrome(n), которая получает на вход значение типа int и возвращает значение типа int.

Вызов функции Возвращаемое значение
next_palindrome(179)
181

I: Минимальный делитель числа

Дано натуральное число \(n>1\). Найдите его наименьший делитель, отличный от 1.

Решение оформите в виде функции min_divisor(n). Алгоритм должен иметь сложность \(O(\sqrt{n})\).

Указание. Если у числа \(n\) нет делителя не превосходящего \(\sqrt{n}\), то число \(n\) — простое и ответом будет само число \(n\).

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
min_divisor(4)
2
min_divisor(5)
5

J: Проверка числа на простоту

Дано натуральное число \(n>1\). Проверьте, является ли оно простым.

Решение оформите в виде функции is_prime(n), которая возвращает True для простых чисел и False для составных чисел. Решение должно иметь сложность \(O(\sqrt{n})\).

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
is_prime(2)
True
is_prime(4)
False

K: Разложение на множители

Дано натуральное число \(n>1\). Постройте его разложение на простые множители. Решение должно быть оформлено в виде функции factor(n), возвращающей список делителей числа в порядке неубывания. Каждый делитель должен быть включен в список с учетом его кратности.

Функция должна перебирать делители до \(\sqrt{n}\), при уменьшении числа \(n\) граница перебора также должна уменьшатся.

Использование функций sqrt, pow, операции ** для извлечения квадратного корня может быть причиной долгого работы программы. Используйте вместо них возведение в квадрат при помощи операции умножения.

Вызов функции Возвращаемое значение
factor(132)
[2, 2, 3, 11]
factor(2)
[2]

Упражнения на рекурсию

L: Возведение в степень

Дано действительное положительное число \(a\) и целое неотрицательное число \(n\). Вычислите \(a^n\) не используя циклы, стандартную функцию pow, операцию **, а используя рекуррентное соотношение \(a^n=a\cdot a^{n-1}\).

Решение оформите в виде функции power(a, n).

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
power(2, 3)
8

M: Числа Фибоначчи

Последовательность Фибоначчи определяется так: \[ \cases{\varphi_0=0, \cr \varphi_1=1, \cr \varphi_{n}=\varphi_{n-1}+\varphi_{n-2} \mbox{, при } n \gt 1.} \]

Напишите функцию fib(n), которая по данному целому неотрицательному n возвращает \(n\)-e число Фибоначчи.

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
fib(6)
8

M+: Полезна ли рекурсия?

Запустите программы, вычисляющие числа Фибоначчи при помощи рекурсивного и нерекурсивного алгоритма. Сравните время их работы для n=10, 20, 30, 40, 50. Объясните результат.

N: Рекурсия вместо цикла

Напишите рекурсивную функцию print_numbers(n), вызов которой приводит к печати на экран натуральных чисел от 1 до \(n\) по одному числу в строке. Циклы и генераторы списков использовать нельзя.

Подсказка. Число \(n\) является параметром. Как свести задачу “вывести числа от 1 до \(n\)” к задаче с меньшим значением параметра?

Сдайте на проверку только тело функции.

Вызов функции Вывод
print_numbers(3)
1
2
3

O: Произведение списка

Напишите функцию product(a), которая по данному списку чисел возвращает произведение элементов данного списка, не используя циклы.

Список содержит только числа, но может быть пустым.

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
product([1, 7, 9])
63

P: Разворот последовательности

Дана последовательность целых чисел, заканчивающаяся числом 0. Выведите эту последовательность в обратном порядке. Сделайте это без использования списков и циклов.

Решение оформите в виде функцииreverse(), не принимающей параметров, которая считывает со стандартного ввода последовательность чисел до появления числа 0 и выводит эту же последовательность в обратном порядке. Функция должна считать одно число и, если это число не 0, вызвать себя рекурсивно.

Сдайте на проверку только тело функции.

Ввод Вывод
1
2
3
0
0
3
2
1

Q: Быстрое возведение в степень

Возводить в степень можно гораздо быстрее, чем за \(n\) умножений! Для этого нужно воспользоваться следующими рекуррентными соотношениями:

\(a^n=(a^2)^{n/2}\) при четном \(n\),

\(a^n=a\cdot a^{n-1}\) при нечетном \(n\).

Реализуйте алгоритм быстрого возведения в степень. Если вы все сделаете правильно, то сложность вашего алгоритма будет \(O(\log n)\).

Решение оформите в виде функции power(a, n). Использовать стандартную функцию pow и оператор ** по-прежнему запрещается.

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
power(1.000000001, 1000000000)
2.718282030814511

R: Алгоритм Евклида

Для быстрого вычисления наибольшего общего делителя двух чисел используют алгоритм Евклида. Он построен на следующем соотношении: \(НОД(a,b)=НОД(a\bmod b,b)\).

Реализуйте рекурсивный алгоритм Евклида в виде функции gcd(a, b), возвращающей искомое значение.

Сдайте на проверку только тело функции.

Вызов функции Возвращаемое значение
gcd(12, 16)
4

S: Ханойские башни

Головоломка “Ханойские башни” состоит из трех стержней, пронумерованных числами 1, 2, 3. На стержень 1 надета пирамидка из \(n\) дисков различного диаметра в порядке возрастания диаметра. Диски можно перекладывать с одного стержня на другой по одному, при этом диск нельзя класть на диск меньшего диаметра. Необходимо переложить всю пирамидку со стержня 1 на стержень 3 за минимальное число перекладываний.

Напишите функцию, которая решает головоломку; для данного числа дисков n печатает последовательность перекладываний в формате a b c, где a — номер перекладываемого диска, b — номер стержня с которого снимается данный диск, c — номер стержня на который надевается данный диск.

Например, строка 1 2 3 означает перемещение диска номер 1 со стержня 2 на стержень 3. В одной строке печатается одна команда. Диски пронумерованы числами от 1 до n в порядке возрастания диаметров.

Программа должна вывести минимальный (по количеству произведенных операций) способ перекладывания пирамидки из данного числа дисков.

Указание: подумайте, как переложить пирамидку из одного диска? Из двух дисков? Из трех дисков? Из четырех дисков? Пусть мы научились перекладывать пирамидку из \(n\) дисков с произвольного стержня на любой другой, как переложить пирамидку из \(n+1\) диска, если можно пользоваться решением для \(n\) дисков.

Решение оформите в виде функции move(n, start, finish), которая печатает последовательность перекладываний дисков для перемещения пирамидки высоты n со стержня номер start на стержень номер finish.

Сдайте на проверку только тело функции.

В примере ниже пирамидка из 2 дисков перекладывается со стержня 1 на стержень 3.

Вызов функции Вывод
move(2, 1, 3)
1 1 2
2 1 3
1 2 3

T: Ремонт в Ханое

Постановлением ЮНЕСКО оригинал Ханойской башни был подвергнут реставрации. В связи с этим во время пользования головоломкой нельзя было перекладывать кольца с первого стержня сразу на третий и наоборот.

Решите головоломку с учетом этих ограничений. Вам не нужно находить минимальное решение, но количество совершенных перемещений не должно быть больше 200000, при условии, что количество дисков не превосходит 10.

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

Тесты к этой задаче закрытые.

Ввод Вывод
1
1 1 2
1 2 3
2
1 1 2
1 2 3
2 1 2
1 3 2
1 2 1
2 2 3
1 1 2
1 2 3

U: Циклические башни

На дорогах Ханоя было введено одностороннее круговое движение, поэтому теперь диск со стержня 1 можно перекладывать только на стержень 2, со стержня 2 на 3, а со стержня 3 на 1.

Решите головоломку с учетом этих ограничений. Вам не нужно находить минимальное решение, но количество совершенных перемещений не должно быть больше 200000, при условии, что количество дисков не превосходит 10.

Ввод Вывод
1
1 1 2
1 2 3
2
1 1 2
1 2 3
2 1 2
1 3 1
2 2 3
1 1 2
1 2 3

V: Несправедливые башни

В Ханое несправедливо запретили класть самый маленький диск (номер 1) на средний колышек (номер 2).

Решите головоломку с учетом этих ограничений. Вам не нужно находить минимальное решение, но количество совершенных перемещений не должно быть больше 200000, при условии, что количество дисков не превосходит 10.

Ввод Вывод
2
1 1 3
2 1 2
1 3 1
2 2 3
1 1 3

W: Сортирующие башни

Первоначально все диски лежат на стержне номер 1. Переместите диски с нечетными номерами на стержень номер 2, а с четными номерами - на стержень номер 3.

Вам не нужно находить минимальное решение, но количество совершенных перемещений не должно быть больше 200000, при условии, что количество дисков не превосходит 10.

Ввод Вывод
2
1 1 2
2 1 3
3
1 1 2
2 1 3
1 2 3
3 1 2
1 3 2

X: Обменные башни

Как и в предыдущих задачах, дано три стержня, на первом из которых надето \(n\) дисков различного размера. Необходимо их переместить на стержень 3 по следующим правилам:

Самый маленький диск (номер 1) можно в любой момент переложить на любой стержень. Перемещение диска номер 1 со стержня a на стержень b будем обозначать 1 a b.

Можно поменять два диска, лежащих на вершине двух стержней, если размеры этих дисков отличаются на 1. Например, если на вершине стержня с номером a лежит диск размером 5, а на вершине стержня с номером b лежит диск размером 4, то эти диски можно поменять местами. Такой обмен двух дисков будем обозначать 0 a b (указываются номера стержней, верхние диски которых обмениваются местами).

Для данного числа дисков \(n\), не превосходящего 10, найдите решение головоломки. вам не нужно находить минимальное решение, но количество совершенных перемещений не должно быть больше 200000.

Ввод Вывод
1
1 1 3
2
1 1 3
0 1 3
1 1 3

Y: Фишки

Дана полоска из клеток, пронумерованных от 1 до N слева направо. Разрешено снимать или ставить фишку на клетку с номером 1 или на клетку, следующую за самой левой из установленных фишек. Изначально полоска пуста. Нужно разместить фишки во всех клетках.

Программа получает на вход количество клеток в полоске \(N\) \((1\le N\le 10)\).

Программа должна вывести последовательность номеров клеток, с которыми совершается действие. Если фишка снимается, то номер клетки должен выводиться со знаком минус. Количество действий не должно превышать \(10^4\). Если существует несколько возможных решений задачи, то разрешается вывести любое.

Тесты к этой задаче закрытые.

Ввод Вывод
3
1 2 -1 3 1

Z: Небоскреб

В небоскребе \(n\) этажей. Известно, что если уронить стеклянный шарик с этажа номер \(p\), и шарик разобьется, то если уронить шарик с этажа номер \(p+1\), то он тоже разобьется. Также известно, что при броске с последнего этажа шарик всегда разбивается.

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

Определите, какого числа бросков достаточно, чтобы заведомо решить эту задачу.

Программа получает на вход количество этажей в небоскребе \(n\) и выводит наименьшее число бросков, при котором можно всегда решить задачу.

Тесты к этой задаче закрытые.

Ввод Вывод
4
2
20
6

Комментарий к первому примеру. Нужно бросить шарик со 2-го этажа. Если он разобьется, то бросим второй шарик с 1-го этажа, а если не разобьется - то бросим шарик с 3-го этажа.

Подсказки.
1. Как следует действовать, если шарик был бы только один?
2. Пусть шариков два и мы бросили один шарик с этажа номер \(k\). Как мы будем действовать в зависимости от того, разобьется ли шарик или нет?
3. Пусть f(n) - это минимальное число бросков, за которое можно определить искомый этаж, если бы в небоскребе было n этажей. Выразите f(n) через значения f(a) для меньших значений a.