Задание №23 — Поиск количества программ
Исполнитель преобразует число на экране. У исполнителя есть две команды, которым присвоены номера:
1) Прибавить 1
2) Умножить на 2
Первая команда увеличивает число на экране на 1, вторая умножает его на 2. Программа для исполнителя — это последовательность команд. Сколько существует программ, для которых при исходном числе 1 результатом является число 20 и при этом траектория вычислений содержит число 10? Траектория вычислений программы — это последовательность результатов выполнения всех команд программы.
Например, для программы 121 при исходном числе 7 траектория будет состоять из чисел 8, 16, 17.
Правильный ответ
28
Пояснение
Решение:
Обозначим через количество программ, переводящих число в заданное конечное число. Из исполнитель может перейти либо в (команда 1), либо в (команда 2), поэтому причём (пустая программа), а если уже больше конечного числа, то — числа только растут.
Траектория обязана содержать 10, а 10 лежит между 1 и 20, поэтому каждая подходящая программа однозначно распадается на две независимые части: сначала , потом . По правилу произведения общее количество равно произведению количеств.
1) Из 1 в 10. Считаем от 10 вниз к 1 (удвоение из сразу перескакивает через 10, поэтому там остаётся только «прибавить 1»):
| 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | |
| 1 | 1 | 1 | 1 | 1 | 2 | 3 | 4 | 7 | 14 |
Например, , , . Итого 14 программ.
2) Из 10 в 20. Для любого удвоение даёт больше 20, значит для всех . А из 10 можно и прибавлять единицы, и сразу удвоить: .
Итого .
from functools import lru_cache
def count(start, finish):
@lru_cache(None)
def R(x):
if x > finish:
return 0
if x == finish:
return 1
return R(x + 1) + R(2 * x)
return R(start)
print(count(1, 10) * count(10, 20))
Ответ: 28