Новогодняя задача: помоги Тирексу нарядить елку

Новогодняя задача: помогите Тирексу поставить нарядить елочку

Тирекс
Тирекс Самый зубастый автор
24 декабря 2024

Это задача для тех, кто настолько любит 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 при умножении символа на число получается строка. Используем это свойство. Далее в каждой строке развесим игрушки. Для этого берем в цикле каждый символ и делаем проверки:

  1. Предыдущий символ равен следующему? Эта проверка позволяет разместить игрушку между ветками.
  2. Рандомное значение меньше порога? Этим условием выбираем, вешать ли игрушку.

Положительный результат обоих условий запускает замену «ветки» на «игрушку». Т. к. строковый объект в 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))