Новогодняя задача: помогите Тирексу поставить нарядить елочку
Это задача для тех, кто настолько любит IT, что даже к главному символу праздника подходит по-айтишному.
Условие
Сисадмин Тирекс засиделся допоздна и не успел не то что нарядить елку, но даже купить ее! У него нет главного символа праздника, но есть компьютер, IDE, технический склад ума и знание Python.
Задача
Помоги Тирексу вывести в консоли наряженную елку на любимом языке программирования. Педантичный Тирекс предъявляет следующие требования:
- на вход программа получает два числа: rows отвечает за высоту елки в строчках (не менее трех), freq — за частоту появления украшений.
- ветки елки — символ *.
- игрушки — символы о, О, @ и 0.
- елка имеет ствол из трех символов | и стоит на полу из символов _.
- ветви елки расположены «ступенями»: первая состоит из трех строк, каждая следующая ниже — на одну больше.
- первая строка следующей ниже «ступени» должна иметь на два символа меньше, чем последняя строка предыдущей.
- елка должна иметь границы в виде символов / и \.
- между двумя украшениями по горизонтали должна быть минимум одна ветка.
- украшения не должны висеть на границе елки (они же упадут!).
Бонусная задача
- вывести снег символом . (точка).
- раскрасить елку зеленым, фон — синим, игрушки — разными цветами (кроме зеленого и синего), снег — белым.
Решение
Рисовать елку будем сверху вниз.
Один из вариантов решения на привычном для Тирекса рептилоидном языке. В самом начале импортируем модуль для работы с рандомными (псевдорандомными) числами. Из всей библиотеки нужна только одна функция генерации чисел по диапазону. Сразу обозначим ее более коротким словом rnd. Далее, в основном коде программы создадим необходимые переменные для работы.
from random import randint as rnd
if __name__ == "__main__":
step_next = 3
step_actual = 0
step_len = 1
toys_varians=["o","O","@","0"]
rows = int(input("Rows: "))
freq = int(input("Frequency: "))
Далее запросим у пользователя исходные данные для «рисования». Важно выполнить преобразование input в целочисленное значение — в дальнейшем будем работать только с полученными цифрами, а преобразование выдаст ошибку. Ошибки можно обрабатывать специальными конструкциями.
Rows: ошибка
Traceback (most recent call last):
File "/Users/vlad_ry/Documents/exp/other/cristmas_tree.py", line 23, in <module>
rows = int(input("Rows: "))
ValueError: invalid literal for int() with base 10: 'ошибка'
Теперь приступим к описанию алгоритма вывода елки. Для этого в цикле сначала задаем строку с ветками. В Python при умножении символа на число получается строка. Используем это свойство. Далее в каждой строке развесим игрушки. Для этого берем в цикле каждый символ и делаем проверки:
- Предыдущий символ равен следующему? Эта проверка позволяет разместить игрушку между ветками.
- Рандомное значение меньше порога? Этим условием выбираем, вешать ли игрушку.
Положительный результат обоих условий запускает замену «ветки» на «игрушку». Т. к. строковый объект в Python неизменяемый, мы переопределяем строку, беря срез до текущего символа и после него, а между ними вставляем новое значение. Последний этап в этом блоке — вывести строку. Для этого пробелами «добиваем» начало и выводим строку веток.
Далее переменными с префиксом step_ подсчитываем уровень. Если достигнута нижняя строка «ступени», уменьшаем следующую строку на 2, обнуляем счетчик и сообщаем, что следующая «ступень» должна быть больше предыдущей на 1.
Последняя строка — вывод ствола елки.
for i in range(0,rows):
br_row = "/" + "*"*(2*step_len-1) + "\\"
if (len(br_row)>1):
for x in range(1,len(br_row)-2):
if (br_row[x+1]== br_row[x-1] and \
rnd(1, 10) <= freq):
br_row = br_row[:x] + toys_varians[rnd(0, 3)] + br_row[x+1:]
print(" "*(rows-step_len) + br_row)
step_actual+=1
step_len+=1
if(step_actual==step_next):
step_len-=2
step_actual=0
step_next+=1
print("_"*(rows-1) + "|||"+"_"*(rows-1))
Таким нехитрым образом можно вывести елку и периодически ее генерировать, меняя частоту появления игрушек и высоту.
А если вы хотите увидеть по-настоящему большую елку, запустите код ниже. В терминале в строке Rows укажите 63, в строке Frequency — 5. Всех с новым годом!
import random
from random import randint as rnd
if __name__ == "__main__":
step_next = 3
step_actual = 0
step_len = 1
toys_varians=["o","O","@","0"]
rows = int(input("Rows: "))
freq = int(input("Frequency: "))
for i in range(0,rows):
br_row = "/" + "*"*(2*step_len-1) + "\\"
if (len(br_row)>1):
for x in range(1,len(br_row)-2):
if (br_row[x+1]== br_row[x-1] and \
rnd(1, 10) <= freq):
br_row = br_row[:x] + toys_varians[rnd(0, 3)] + br_row[x+1:]
print(" "*(rows-step_len) + br_row)
step_actual+=1
step_len+=1
if(step_actual==step_next):
step_len-=2
step_actual=0
step_next+=1
print("_"*(rows-1) + "|||"+"_"*(rows-1))