К содержанию

Задание 13

Анализ хода исполнения алгоритма

Как посчитать программы исполнителя, не выписывая их: дерево, таблица и программа на Python — с обязательными и запрещёнными числами и разными командами.

7 подтем · 43 задачи + 11 дополнительных · повышенный · ≈ 7 мин

Подтема 1 из 7

Команды, программы и дерево

Что такое программа и траектория, как перебрать все программы деревом и почему его можно сократить.

Как устроена тема

В задании 13 исполнитель меняет число своими командами, а спрашивают, сколько разных программ ведут от одного числа к другому. Вот задача, которую мы будем решать всю тему:

«Исполнитель преобразует число на экране. У исполнителя есть две команды, которым присвоены номера: 1. Прибавить 1; 2. Умножить на 2. Программа для исполнителя — это последовательность команд. Сколько существует программ, для которых при исходном числе 2 результатом является число 20, и при этом траектория вычислений содержит число 6 и не содержит числа 9? Траектория вычислений программы — это последовательность результатов выполнения всех команд программы.»

Выписывать все программы долго — их много, и они длинные. Мы научимся считать их, не выписывая. Сначала разберём, что сказано в условии:

В условииЧто это значит
команды 1 и 21 — прибавить 1, 2 — умножить на 2; программу пишут номерами: 121 — это «прибавить, умножить, прибавить»
исходное число 2, результат 20начинаем с 2, после последней команды на экране 20
траекториячисла на экране после каждой команды
содержит 66 хотя бы раз появилось на экране
не содержит 99 не появилось ни разу
сколько существует программпосчитать все подходящие программы

Тема состоит из семи подтем — у каждой своя страница. Идём по ним по порядку:

  1. Команды, программы и дерево — ты сейчас здесь.
  2. Таблица количества программ — тот же счёт без дерева для участка из 6 в 20.
  3. Обязательные и запрещённые числа — обязательное 6, запрещённое 9 и ответ задачи.
  4. Новые и условные команды — другие команды вместо «+1» и «×2».
  5. Убывание и деление — команды, которые уменьшают число.
  6. Группы программ и обратные вопросы — дополнительный урок для редких условий.
  7. Длина и память программы — ещё один дополнительный урок.

Почти везде задачу можно решить и вручную, и программой — выбирай вкладку «Вручную» или «Python». На экзамене подойдёт любой способ, а второй пригодится для проверки.

Программа и траектория

Возьмём исходное число 3 и выполним две программы: 12 и 21.

Программа — последовательность команд, записанная их номерами. Команды выполняют слева направо, по одной. Программа 12: сначала команда 1 — 3 + 1 = 4, потом команда 2 — 4 · 2 = 8. Программа 21 — те же команды в другом порядке: 3 · 2 = 6, потом 6 + 1 = 7.

Программы 12 и 21 из числа 3: над стрелкой — номер команды и что она делает, под числами — траектория.

Траектория — числа, которые появились на экране после каждой команды: у программы 12 это 4 и 8, у программы 21 — 6 и 7. Исходное число 3 в траекторию не входит: его не получала ни одна команда.

Обрати внимание: считают программы, а не числа. Из 1 команда 1 даёт 1 + 1 = 2 и команда 2 даёт 1 · 2 = 2. Число одно, а программы две — 1 и 2. Поэтому из 1 в 4 ведут четыре программы: 111, 12, 21 и 22.

Тонкости:длина и направление

Если длина не ограничена, считают программы любой длины, а не только самые короткие.

Команды «+1» и «×2» на положительных числах только увеличивают число: перешагнув цель, к ней уже не вернуться, поэтому программ конечное число. Но так бывает не всегда: из 0 умножение на 2 снова даёт 0, а квадрат из 1 — снова 1. Такую команду можно повторять сколько угодно раз, и программ становится бесконечно много.

Дерево вариантов

Сколько программ переводят 2 в 6 — первый участок задачи темы?

Дерево перебирает все программы: из каждого числа выходит по ветке на каждую команду. Строим его от 2:

  1. Из 2 команда 1 даёт 3, команда 2 — 4: две ветки.
  2. Из каждого нового числа снова пробуем обе команды.
  3. Получили 6 — ветка закончилась успехом: это одна программа.
  4. Получили больше 6 — ветку обрываем: команды только увеличивают число, к 6 уже не вернуться.
Все программы из 2 в 6. Пройди от 2 до оранжевого листа и выпиши номера команд на ветках — получишь программу: 1111, 12, 211. Пунктирные листы перепрыгнули 6.
Вручную

Слева идём через 3: дальше 3 → 4 → 5 → 6 — это программа 1111, а 3 · 2 = 6 — программа 12. Справа через 4: 4 → 5 → 6 — программа 211, а 4 · 2 = 8 уже больше 6. Успешных листьев три — значит, и программ три.

Python

В коде дерево превращается в — функцию, которая вызывает сама себя для каждой ветки. Функцию f(x, y) задаём через , она считает программы из x в y. Каждая её строка с или return — одно правило дерева:

  1. if x > y: return 0 — ветка перепрыгнула цель, программ нет;
  2. if x == y: return 1 — дошли до цели, это одна программа;
  3. f(x + 1, y) + f(x * 2, y) — две ветки, их программы складывают.
def f(x, y):    if x > y:        return 0    if x == y:        return 1    return f(x + 1, y) + f(x * 2, y)  print(f(2, 6))
3

Раскрутку одной ветки дерева — из 3 в 6 — пройди по шагам:

def f(x, y):    if x > y:        return 0    if x == y:        return 1    return f(x + 1, y) + f(x * 2, y) print(f(3, 6))
2

Повторы в дереве

В дереве число 4 встретилось дважды: слева — после 2 → 3 → 4, справа — сразу после 2 → 4. Нужно ли продолжать его два раза?

Из одинаковых чисел дерево растёт одинаково, поэтому число достаточно записать один раз и отметить, сколькими программами в него пришли. В 4 пришли две программы (11 и 2), и каждую можно продолжить одинаково: 4 → 5 → 6. Значит, через 4 в 6 ведут две программы.

Это количество обозначают K(n): сколько программ переводят старт в число n. Запишем числа от 2 до 6 в строку, а под каждым — K:

Те же программы в таблице: K(4) = 2 — в 4 ведут 11 и 2; K(6) = 3, как и в дереве. Соседние клетки связывает «+1», дуги — «×2».

Такая таблица заменяет дерево, когда чисел много, — ей посвящена подтема 2.

Итого

  • Программапоследовательность команд
  • Разные программыразный порядок команд, даже при одном результате
  • Траекториячисла после команд, без старта
  • Деревоветка на команду, обрыв за целью
  • Повторычисло один раз, под ним K(n)
  • Pythonf(x + 1, y) + f(x * 2, y)

Проверьте себя

Ответь сначала сам, потом открой ответ.

Вопрос 1
Команды «+1» и «×2», исходное число 3. Какое число даст программа 121?
ОтветСкрыть ответ
Ответ
9: 3 + 1 = 4, 4 · 2 = 8, 8 + 1 = 9.
Вопрос 2
Сколько программ из команд «+1» и «×2» переводят 3 в 9?
ОтветСкрыть ответ
Ответ
3: 111111, 121 (3 → 4 → 8 → 9) и 2111 (3 → 6 → 7 → 8 → 9).
Вопрос 3
Сколько программ из команд «+1» и «+2» переводят 2 в 6?
ОтветСкрыть ответ
Ответ
5: 1111, 112, 121, 211, 22.
Вопрос 4
Из 1 обе команды «+1» и «×2» дают 2. Сколько программ переводят 1 в 4?
ОтветСкрыть ответ
Ответ
4: 111, 21, 12 и 22 — первые команды «+1» и «×2» разные, хотя числа одинаковые.
Вопрос 5
Почему из 0 командами «+1» и «×2» в 1 ведёт бесконечно много программ?
ОтветСкрыть ответ
Ответ
0 · 2 = 0: умножение не меняет 0, его можно повторять сколько угодно раз перед «+1».

Практика

Для проверки ответов нужен JavaScript. Условия, подсказки и решения доступны ниже.

Результат программы 121

Команда 1 прибавляет 1, команда 2 умножает на 2. Какое число получится из 3 после выполнения программы 121?

Введите число.

Программы из 3 в 9

Команды «+1» и «×2». Сколько программ переводят 3 в 9?

Введите число.

Программы из 3 в 10

Команды «+1» и «×2». Сколько программ переводят 3 в 10?

Введите число.

Из 1 в 9: +1 и ×3

Исполнитель преобразует число на экране. У исполнителя есть две команды: 1. Прибавить 1; 2. Умножить на 3. Программа для исполнителя — это последовательность команд. Сколько существует программ, для которых при исходном числе 1 результатом является число 9?

Введите число.

Что выведет эта программа?

def f(x, y):    if x > y:        return 0    if x == y:        return 1    return f(x + 1, y) + f(x * 2, y)  print(f(2, 8))

Введите число.