Задание №23 — Поиск количества программ
Исполнитель преобразует число на экране. У исполнителя есть три команды, которые обозначены латинскими буквами:
А) Прибавить 3
В) Прибавить 4
С) Умножить на 3
Первая из них увеличивает число на экране на 3, вторая увеличивает его на 4, третья умножает его на 3.
Программа для исполнителя — это последовательность команд. Сколько существует таких программ, которые преобразуют исходное число 1 в число 30 и при этом траектория вычислений программы содержит число 7?
Траектория вычислений программы — это последовательность результатов выполнения всех команд программы. Например, для программы АСВ при исходном числе 2 траектория будет состоять из чисел 5, 15, 19.
Правильный ответ
58
Пояснение
Решение:
Все команды только увеличивают число на экране, поэтому траектория строго возрастает и ни одно число не может встретиться в ней дважды.
Траектория обязана содержать число , поэтому каждая подходящая программа однозначно распадается на две части: и . По правилу умножения ответ равен произведению количеств программ для этих участков.
Пусть — количество программ, переводящих в : (пустая программа), при (число уже «перескочило» цель, а уменьшать команды не умеют). В остальных случаях перебираем первую команду («прибавить 3», «прибавить 4» или «умножить на 3»):
from functools import lru_cache
@lru_cache(None)
def f(x, y): # сколько программ переводят число x в число y
if x == y:
return 1
if x > y:
return 0 # перескочили - назад команд нет
s = 0
for z in (x + 3, x + 4, x * 3):
s += f(z, y)
return s
print(f(1, 7) * f(7, 30))
Получаем и , то есть всего программ.
Ответ: 58