Для выполнения задания найди ссылку-приглашение в онлайн чате, получи доступ к репозиторию с файлом-заготовкой и заполни пропуски в нём. Фиксируй изменения (делай коммиты) после решения каждой задачи. Оставь название файла неизменным, иначе робот-проверятель не найдёт твои ответы. Отправить решения на GitHub нужно до истечения установленного срока. |
Деревья
Вопрос 1
Сделай функцию replace_leaf
, которая принимает дерево t
, старое значение old
и новое значение new
. Функция должна возвратить новое дерево, в котором заменены все листья со значением old
на листья со значением new
.
def replace_leaf(t, old, new):
"""Возвращает новое дерево, в котором все листы со значением old заменены на new.
>>> yggdrasil = tree('odin',
... [tree('balder',
... [tree('thor'),
... tree('loki')]),
... tree('frigg',
... [tree('thor')]),
... tree('thor',
... [tree('sif'),
... tree('thor')]),
... tree('thor')])
>>> laerad = copy_tree(yggdrasil) # копирование yggdrasil для тестирования
>>> print_tree(replace_leaf(yggdrasil, 'thor', 'freya'))
odin
balder
freya
loki
frigg
freya
thor
sif
freya
freya
>>> laerad == yggdrasil # Проверка, что исходное дерево не изменилось
True
"""
"*** ТВОЙ КОД ЗДЕСЬ ***"
Мобили
Мобиль — это вид висячей скульптуры (кинетическое искусство). Бинарный мобиль mobile
состоит из двух ветвей (сторон) — левой left
и правой right
. Каждая сторона side
представляет собой стержень определенной длины length
, с которого свисает либо груз weight
, либо другой бинарный̆ мобиль.
Бинарный мобиль можно представить в виде абстрактного типа данных.
Длина стержня и вес гирьки должны быть больше нуля.
def mobile(left, right):
"""Создаёт мобиль из правой и левой сторон."""
assert is_side(left), "Аргумент left должен быть стороной (side)"
assert is_side(right), "Аргумент right должен быть стороной (side)"
return ['mobile', left, right]
def is_mobile(m):
"""Проверяет, что m является мобилем."""
return type(m) == list and len(m) == 3 and m[0] == 'mobile'
def left(m):
"""Возвращает левую сторону мобиля."""
assert is_mobile(m), "Аргумент m должен быть мобилем (mobile)"
return m[1]
def right(m):
"""Возвращает правую сторону мобиля."""
assert is_mobile(m), "Аргумент m должен быть мобилем (mobile)"
return m[2]
def side(length, mobile_or_weight):
"""Создаёт ветвь (сторону) из длины стержня length и одного из:
мобиля mobile или груза weight."""
assert is_mobile(mobile_or_weight) or is_weight(mobile_or_weight)
return ['side', length, mobile_or_weight]
def is_side(s):
"""Проверяет, что s — сторона side."""
return type(s) == list and len(s) == 3 and s[0] == 'side'
def length(s):
"""Возвращает длину стержня стороны."""
assert is_side(s), "Аргумент s должен быть стороной (side)"
return s[1]
def end(s):
"""Возвращает мобиль или груз."""
assert is_side(s), "Аргумент s должен быть стороной (side)"
return s[2]
Вопрос 2
Реализуй абстракцию «груз», дополнив конструктор weight
и селектор size
так, чтобы гирька представлялась двухэлементным списком, первый элемент которого должен быть строкой weight
. Пример total_weight
приведён для демонстрации абстракций mobile
, side
, weight
.
def weight(size):
"""Создаёт груз размера size."""
assert size > 0
"*** ТВОЙ КОД ЗДЕСЬ ***"
def size(w):
"""Возвращает размер груза."""
assert is_weight(w), 'Аргумент w должен быть грузом (weight)'
"*** ТВОЙ КОД ЗДЕСЬ ***"
def is_weight(w):
"""Проверяет, что w — груз."""
return type(w) == list and len(w) == 2 and w[0] == 'weight'
Вопрос 3
Создай функцию balanced
, проверяющую, что мобиль m
сбалансирован. Мобиль считается таковым при соблюдении двух условий:
-
если момент вращения, действующий на его левую ветвь, равен моменту вращения, действующему на правую ветвь (то есть длина левого стержня, умноженная на вес груза, свисающего с него, равна соответствующему произведению для правой стороны);
-
если все подмобили, свисающие с его ветвей, также сбалансированы.
Можно предположить, что грузы обладают свойством балансировки и сбалансированы. |
def balanced(m):
"""Проверяет, что мобиль m сбалансирован.
>>> t, u, v = examples()
>>> balanced(t)
True
>>> balanced(v)
True
>>> w = mobile(side(3, t), side(2, u))
>>> balanced(w)
False
>>> balanced(mobile(side(1, v), side(1, w)))
False
>>> balanced(mobile(side(1, w), side(1, v)))
False
"""
"*** ТВОЙ КОД ЗДЕСЬ ***"
Вопрос 4
Реализуй функцию totals_tree
, которая принимает мобиль m
(или груз) и возвращает дерево, у которого корневое значение равно полному весу мобиля, а ветви являются поддеревьями для сторон мобиля.
def totals_tree(m):
"""Возвращает дерево, описывающее распределение веса в мобиле.
>>> t, u, v = examples()
>>> print_tree(totals_tree(t))
3
2
1
>>> print_tree(totals_tree(u))
6
1
5
3
2
>>> print_tree(totals_tree(v))
9
3
2
1
6
1
5
3
2
"""
"*** ТВОЙ КОД ЗДЕСЬ ***"