Задание №23 — Поиск количества программ
Исполнитель преобразует число на экране. У исполнителя есть две команды, которые обозначены латинскими буквами:
А) Вычти 1
В) Найди целую часть от деления на 2
Программа для исполнителя — это последовательность команд. Сколько существует программ, для которых при исходном числе 60 результатом является число 1, и при этом траектория вычислений содержит число 20 и не содержит 4? Траектория вычислений программы — это последовательность результатов выполнения всех команд программы.
Например, для программы АВВ при исходном числе 10 траектория состоит из чисел 9, 4, 2.
Правильный ответ
1760
Пояснение
Решение:
Обе команды только уменьшают число на экране, поэтому траектория строго убывает и одно и то же число не может встретиться в ней дважды. Значит, каждая подходящая программа однозначно разбивается на две независимые части: сначала число превращается в , затем превращается в . По правилу умножения искомое количество равно произведению количеств программ для этих двух участков.
Пусть — количество программ, переводящих в . Если , подходит только пустая программа, то есть ; если , то — увеличивать число команды не умеют. Иначе первая команда переводит либо в , либо в , поэтому
Число в траектории появляться не должно, поэтому переход в него просто запрещаем — соответствующее слагаемое не учитываем.
from functools import lru_cache
@lru_cache(None)
def f(x, y): # сколько программ переводят x в y, минуя число 4
if x == y:
return 1
if x < y:
return 0
s = 0
for z in (x - 1, x // 2):
if z != 4:
s += f(z, y)
return s
print(f(60, 20) * f(20, 1))
Получаем и , то есть всего программ.
Ответ: 1760