День четвертый. Как много в этом звуке…


Прикончить того, кто придумывает вот такое зубодробительное:

Исполнитель А16 преобразует число, записанное на экране.

У исполнителя есть три команды, которым присвоены номера:

1.  Прибавить 1

2.  Прибавить 2

3.  Умножить на 2

Первая из них увеличивает число на экране на 1, вторая увеличивает его на 2, третья умножает его на 2.

Программа для исполнителя А16 – это последовательность команд.

Сколько существует таких программ, которые исходное число 3 преобразуют в число 12 и при этом траектория вычислений программы содержит число 10?

Пока дочитаешь до конца, забудешь, с чего все начиналось. Но жизнь вообще трудна, а тут всего-навсего задание 23 егэ информатика, поэтому втыкаем на вопрос, который поместился в самом конце: “Сколько существует таких программ, которые исходное число 3 преобразуют в число 12 и при этом траектория вычислений программы содержит число 10?”.

Выглядит как какая-то комбинаторика, надо найти количество “траекторий” (что бы это ни значило) от 3 до 10, потом – от 10 до 12 и эти два количества перемножить. Самой не сообразить, открываю код решения и тупо смотрю на него.

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

Итак, одна-единственная функция (с двумя входными переменными), которая вызывает сама себя (привет, рекурсия). Все, что нужно – это вызвать ее для первой “траектории” (параметры 3 и 10), потом – для второй (параметры 10 и 12), перемножить результат и напечатать его в консоли.

В упор не понимаю, зачем в начале две проверки, которые возвращают 0 или 1. Выглядит, как количество траекторий: их или нет (возвращаем 0), или 1 (траектория от числа к тому же числу). Примерно как мой заработок на размещении рекламы – его или нет, или мало.

Вся логика сосредоточена в третьем return:

return f(x + 1, y) + f(x + 2, y) + f(x * 2, y)

По ходу, эта штука связана с условием:

У исполнителя есть три команды, которым присвоены номера:

1.  Прибавить 1

2.  Прибавить 2

3.  Умножить на 2

Да, так и есть, к первому операнду прибавляем 1, потом 2, потом умножаем на 2. И результаты складываем. Хватит думать, понятнее как решить задание 23 егэ информатика уже не станет, погнали писать код.

Для начала – создадим функцию f (говорящее название, ага), но уже с двумя входными переменными – x и y. Автор решения явно обделен воображением. Ну или ему лень тыкать много клавиш (как и мне). File-New-ege-23-1.py. Вижу я чистый лист..

А, и да, вызвать ее для (3,10), потом – для (10,12); результат перемножить. Пишем print, запускаем, ждем… Результат = 0. Прога есть, но она не работает.

Фак, ну что может пойти не так в куске кода на 3 строчки?? С другой стороны, нельзя же все время писать без ошибок. Еще раз, строчка за строчкой.

def f(x,y):
    if x<y: return 0

Возвращаем 0 траекторий, если x меньше y. Блин, вот он, чертов баг. Почему меньше? Ведь правильно – больше. Это от 5 до 1 ни одной траектории, а от 1 до 5 – ну, сколько-то будет. Меняем знак, жмем, заработало!

По-хорошему, еще бы пару примеров разобрать, но этот баг вывел меня. Закругляюсь. А завтра будет День пятый. И вновь продолжается бой