Главная › ЕГЭ по информатике › Задание 13
ЕГЭ по информатике · задание №13

Задание 13: считаем программы исполнителя на Python

Переносим команды в функцию, останавливаем неверные ветки и считаем пути через нужное число. Два разбора по шпаргалке, наглядные короткие программы и практика с нуля.

Пишем решение вместе

Научись выполнять задание 13 своим кодом

Пройди шаги: пойми действие, напиши строки, запусти Python и проверь значения. Затем реши задачу с пустого редактора.

Команды +1, ×2, ×3. Найди число программ из START в TARGET, не содержащих FORBIDDEN.

1. Перевести три команды

Запиши результаты a, b, c трёх команд из текущего x.

Это три отдельных варианта следующего шага. Целая часть деления записывается //, не /.

Строки этого шага и порядок действий

x = 2
a = x + 1
b = x * 2
c = x * 3
Дано для запуска

Эти переменные уже доступны в редакторе. Используй их в решении.

Tab — 4 пробела для отступа · Ctrl+Enter — проверка · код сохраняется в этом браузере

Python работает в браузере. Первый запуск загружает среду и требует интернета; затем можно запускать и исправлять код здесь.

Вывод программы

Здесь появится вывод print.

Значения после выполнения

Запусти код, чтобы увидеть значения.

Скачать все учебные программы и условия этого задания

Видеоразбор

Видео по заданию №13

Видео скоро выйдет.

Шпаргалка, дополнительные разборы и упражнения
Два направления из шпаргалки

Задание 13 ЕГЭ: как превратить команды в подсчёт программ

Нужно посчитать разные последовательности команд, переводящие начальное число в конечное. Мы не выписываем все длинные программы: функция f считает, сколько продолжений есть из текущего состояния.

старт→ выбор команд →текущее x→цель y
Вопрос к условиюЕсли идём вверхЕсли идём вниз
Какие команды?+1, ×2, ×3−1, −3, целая часть от деления на 2
Когда цель уже недостижима?x > yx < y
Что возвращаем при выходе за цель или запрете?00
Что возвращаем, когда дошли?11

Эти шаблоны работают, когда все команды строго движут число в одном направлении в рассматриваемом диапазоне. Тогда после перелёта вернуться нельзя, а рекурсия заканчивается. Для команд, которые могут вернуть к прежнему числу, такой шаблон нельзя переносить без изменений.

Смысл короткой функции

f(x, y) возвращает количество программ из x в y

СитуацияРезультатПочему
Попали в запрещённое числоreturn 0Такая ветка не даёт допустимых программ.
Перешли цель по направлению командreturn 0Все следующие команды уводят ещё дальше.
Дошли до целиreturn 1Есть один готовый способ закончить: больше ничего не делать.
Ещё не дошлиСумма f для результатов каждой командыПервую команду можно выбрать разными способами; считаем все продолжения.

Число 1 при достижении цели — не значение на экране и не число выполненных команд. Это одна завершённая программа. Если вернуть 0, она исчезнет из суммы и весь подсчёт обнулится.

Проверка запрета стоит перед проверкой x == y. Поэтому даже достижение запрещённого конечного состояния не даст допустимого пути.

Тип 1 · число увеличивается

Из 2 в 39, не попадая в 14

Команды исполнителя: прибавить 1, умножить на 2, умножить на 3. Сколько программ переводят 2 в 39, если траектория не содержит 14?

1. Переносим команды в вызовы

КомандаСледующее состояниеКоличество продолжений
Прибавить 1x + 1f(x + 1, y)
Умножить на 2x * 2f(x * 2, y)
Умножить на 3x * 3f(x * 3, y)

Второй аргумент y остаётся тем же: после каждой команды цель не меняется. Между вызовами ставим +, потому что это варианты выбора следующей команды.

2. Выбираем две причины вернуть ноль

if x > y or x == 14:
    return 0

x > y отсекает перелёт, x == 14 — запрет из условия. Здесь нужен or: достаточно любой причины. Значение x = 39 ещё не является перелётом, поэтому сравнение строгое.

3. Собираем полную программу

Тип 1 · движение вверх
def f(x, y):
    if x > y or x == 14:
        return 0
    if x == y:
        return 1
    return f(x + 1, y) + f(x * 2, y) + f(x * 3, y)

print(f(2, 39))
Ответ: 188Все 188 программ доходят от 2 до 39 и обходят 14.

Как складывается первый шаг

Из 2 получаем 3, 4 или 6. Значит f(2, 39) = f(3, 39) + f(4, 39) + f(6, 39). Запрет 14 действует внутри каждого вызова, а не только на первом шаге.

Тип 2 · число уменьшается

Из 19 в 3 через 12, без числа 9

Команды: вычесть 1, вычесть 3, найти целую часть от деления на 2. Посчитай программы из 19 в 3. Траектория содержит 12 и не содержит 9.

1. Меняем направление остановки и команды

Было при движении вверхСтало при движении вниз
x > yx < y
Запрет x == 14Запрет x == 9
x + 1x - 1
x * 2x - 3
x * 3x // 2

Для целой части деления используем //: например, 19 // 2 = 9. Обычное / дало бы 9.5 и не выполнило бы команду из условия.

2. Разбиваем путь по обязательному числу

19→ f(19, 12) →12→ f(12, 3) →3

Для первого отрезка цель y равна 12: если команда перепрыгнула с числа выше 12 сразу ниже 12, вернуться уже нельзя. Такой путь правильно получает 0.

3. Умножаем количества двух частей

Тип 2 · движение вниз через обязательное число
def f(x, y):
    if x < y or x == 9:
        return 0
    if x == y:
        return 1
    return f(x - 1, y) + f(x - 3, y) + f(x // 2, y)

print(f(19, 12) * f(12, 3))

Программ из 19 в 12 без 9 — 9, а из 12 в 3 без 9 — 17. Любую первую часть можно продолжить любой второй: 9 × 17 = 153. Оба вызова используют одну функцию с запретом 9.

Ответ: 153Просто f(19, 3) посчитало бы также программы, которые обходят 12, — это другой вопрос.
Не перепутай два действия

Внутри f складываем, между обязательными этапами умножаем

Что соединяемЗнакСмысл
Выбор следующей команды+Программа начинает с первой, второй или третьей команды.
Обязательные последовательные части*Сначала одна часть пути, потом другая; берём все их сочетания.

Если нужно обязательно пройти два числа в порядке движения, например 6, затем 18, при увеличении от 2 к 24 получится f(2, 6) * f(6, 18) * f(18, 24). Промежуточные числа должны располагаться в достижимом порядке; запреты по-прежнему проверяются внутри f.

Разные команды могут дать одинаковое следующее числоИз 6 команды «вычесть 3» и «целая часть от деления на 2» обе приводят к 3. Это две разные однокомандные программы. Поэтому два вызова f(3, 3) нужно сложить отдельно. Не убирай одинаковые результаты через set.
Посмотри на короткие программы

Почему каждая ветка вносит своё количество

В маленьких примерах можно увидеть все допустимые программы. Выбери пример: таблица покажет результат каждой первой команды и количество продолжений из него. Ниже перечислены сами программы A, B, C и числа на их пути.

Когда шаблон уже понятен

Как ускорить повторные вычисления

Одно и то же f(x, y) может встречаться во многих ветках. Чтобы не считать его заново, можно добавить импорт и декоратор @lru_cache(maxsize=None) прямо над определением функции:

Тот же второй разбор с запоминанием результатов
from functools import lru_cache

@lru_cache(maxsize=None)
def f(x, y):
    if x < y or x == 9:
        return 0
    if x == y:
        return 1
    return f(x - 1, y) + f(x - 3, y) + f(x // 2, y)

print(f(19, 12) * f(12, 3))

Ответ остаётся 153. Кеш хранит количество продолжений, поэтому одинаковые результаты разных команд всё равно складываются столько раз, сколько команд их дают.

Нужен ли setrecursionlimit из шпаргалки?

В этих двух небольших примерах длина пути мала, и увеличивать лимит не требуется. setrecursionlimit меняет разрешённую глубину вызовов, а не число программ и не скорость вычисления. При повторных расчётах ускорение даёт кеш. Для большого диапазона можно использовать подсчёт по состояниям без рекурсивных вызовов.

О кешировании: документация Python.

Попробуй написать код сам

Собери три программы и проверь их вывод

В новых задачах изменены данные. Заполни пропуски выражениями из разобранных шаблонов, скопируй собранный код в свой редактор Python, запусти и введи итоговый ответ. Для следующего шага в учебном архиве есть условия с пустым местом для твоего решения.

Кнопка «Проверить строки» сравнивает фрагменты с шаблоном. Страница не исполняет введённый Python. Другие способы проверяй запуском в своём редакторе и по числовому ответу. Пробелы между частями выражения и обычные одинарные или двойные кавычки допустимы.

Решено: 0 из 12

Сборка 1. Движение вверх без запретного числа

Команды: +1, ×2, ×3. Посчитай программы из 2 в 20. Траектория не содержит 7.
def f(x, y):
    if ⟦1⟧ or x == ⟦2⟧:
        return 0
    if x == y:
        return 1
    return f(⟦3⟧, y) + f(⟦4⟧, y) + f(⟦5⟧, y)

print(⟦6⟧)

1. Какой ответ напечатала программа?

Введи одно итоговое число после запуска своего решения.

Сборка 2. Движение вниз через обязательное число

Команды: −1, −3, целая часть от деления на 2. Посчитай программы из 17 в 3. Траектория не содержит 8 и обязательно содержит 10.
def f(x, y):
    if ⟦1⟧ or x == ⟦2⟧:
        return 0
    if x == y:
        return 1
    return f(⟦3⟧, y) + f(⟦4⟧, y) + f(⟦5⟧, y)

print(⟦6⟧)

2. Какой ответ напечатала программа?

Введи одно итоговое число после запуска своего решения.

Сборка 3. Движение вверх через обязательное число

Команды: +1, ×2, ×3. Посчитай программы из 2 в 24. Траектория не содержит 10 и обязательно содержит 6.
def f(x, y):
    if ⟦1⟧ or x == ⟦2⟧:
        return 0
    if x == y:
        return 1
    return f(⟦3⟧, y) + f(⟦4⟧, y) + f(⟦5⟧, y)

print(⟦6⟧)

3. Какой ответ напечатала программа?

Введи одно итоговое число после запуска своего решения.

Ещё девять вопросов по коду

Ответы можно исправлять и проверять снова.

4. Запрет состояния

В первом разборе чему равно f(14, 39)?

5. Пришли в цель

В первом разборе чему равно f(39, 39)?

6. Перелетели цель

В первом разборе чему равно f(40, 39)?

7. Целая часть

Чему равно 19 // 2?

8. Обязательное число

Между f(19, 12) и f(12, 3) какой знак нужен для пути через 12? Впиши + или *.

9. Сочетания частей

До обязательного числа есть 9 программ, после него — 17. Сколько полных программ?

10. Разные команды с одинаковым итогом

Из 6 команды «−3» и «//2» обе сразу дают 3. Сколько разных однокомандных программ здесь достигли 3?

11. Граница при движении вниз

Второй тип: x = 2, y = 3. Должна ли функция вернуть 0 из-за выхода ниже цели? Ответь «да» или «нет».

12. Средняя цель

В вызове f(19, 12) какое значение y?

Напиши с чистого листа

Скачать Python и задания для самостоятельного решения

Четыре готовых файла: движение вверх, вниз через обязательное число, кеширование и проверка множителей пути. В папке practice — три новых условия с местом для твоего кода; в solutions — решения для сверки после попытки.

Скачать учебные файлы PythonРаспакуй архив, открой нужный .py и запусти в Python 3. Дополнительные библиотеки и файлы данных не нужны.

Если ответ не совпадает

Что проверитьКак исправить
Ответ всегда нольПроверь return 1 при x == y и направление выхода > или <.
Рекурсия идёт от цели к стартуПроверь аргументы: первым текущий старт, вторым цель отрезка.
Не учтён запретУсловие x == запрещённое_число должно проверяться внутри каждого вызова.
Посчитано слишком много путейОбязательное число требует разбиения на части. Одного f(старт, финиш) недостаточно.
В формуле получилась сумма частей путиМежду обязательными отрезками нужно умножение.
Команда деления даёт дробьДля целой части нужен //, не /.
После замены списка результатов на set ответ уменьшилсяРазные команды считаются отдельно; одинаковые следующие числа нельзя объединять.
Повышение лимита не ускорило программуЛимит касается глубины вызовов. Повторные расчёты ускоряет кеш.
Новый набор команд зациклилсяШаблон рассчитан на строгий рост или строгое уменьшение. Если команда оставляет число тем же или возвращает назад, сначала нужен другой учёт состояний.

Вопросы по решению кодом

Что означает f(x, x) = 1?

Если x не запрещён, до цели уже дошли. Пустое продолжение — один способ завершить текущую программу. Если x запрещён, первая проверка вернёт 0.

Почему y не меняется в рекурсивных вызовах?

Внутри одного отрезка цель остаётся той же. Меняется только текущее число x после выбранной команды. Другая цель появляется в отдельном вызове для другого обязательного отрезка.

Можно ли убрать запрет только на втором отрезке?

Проще и надёжнее оставить его в одной общей функции. Если запрещённое число недостижимо на каком-то отрезке, проверка просто не сработает; если достижимо — она нужна.

Где повторить нужный приём Python?

Открой учебник, повтори конкретный приём и вернись к самостоятельному решению. Здесь разобраны строки, которые нужны именно для задания 13.

Проверь, что можешь восстановить решение сам

Возьми условие из папки practice и напиши код в пустом файле. Перед запуском объясни себе каждое ограничение и последнюю строку ответа. Затем переходи к практике на новых заданиях.