Программирование игр и головоломок.

Таинственные программы.

Я надеялся не приводить в этой книге никаких готовых программ. Программирую не я, а вы. И я не очень люблю смотреть, как подростки копируют программу, набирая ее на клавиатуре и при этом не отдавая себе отчета в том, что она делает и как устроена. Но сказать, что делает та или иная программа, может оказаться настоящей головоломкой, Программы, которые мы будем обсуждать, написаны на некотором воображаемом языке[10]. Вам придется по крайней мере сделать усилие, чтобы перевести их на ваш обычный язык: Бейсик, LSE или Паскаль. Условная команда записывается в виде.

ЕСЛИ условие ТО последовательность команд.

КОНЕЦ_ЕСЛИ.

(последовательность команд выполняется тогда и только тогда, когда условие истинно).

Или.

ЕСЛИ условие ТО последовательность команд.

ИНАЧЕ последовательность команд.

КОНЕЦ_ЕСЛИ.

(если условие истинно, то выполняется последовательность команд, заключенная между ТО и ИНАЧЕ, в противном случае выполняется та последовательность команд, которая расположена между ИНАЧЕ и КОНЕЦ_ЕСЛИ).

В обоих случаях КОНЕЦ_ЕСЛИ играет роль закрывающей скобки, связанной с открывающей скобкой ЕСЛИ. Мы будем использовать цикл.

ПОКА условие ВЫПОЛНЯТЬ.

Последовательность команд.

ВЕРНУТЬСЯ.

Последовательность команд, содержащаяся между ВЫПОЛНЯТЬ и ВЕРНУТЬСЯ, повторяется, ПОКА условие истинно.

* Головоломка 17. Для забавы. Вот легко понимаемая программа. Здесь n и b — два натуральных числа и b нечетно (это существенно).

ПРОЧЕСТЬ n, b.

ПОКА n > b ВЫПОЛНЯТЬ.

ЕСЛИ n четно ТО n := n/2.

ИНАЧЕ n := n − b.

КОНЕЦ_ЕСЛИ.

ВЕРНУТЬСЯ.

СООБЩИТЬ ЕСЛИ n = 0 ТО 'ДА'.

ИНАЧЕ 'НЕТ' КОНЕЦ_ЕСЛИ.

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

N = 277 − 3, b = 7.

Забавно, не правда ли? Несмотря на свою исключительную» простоту, эта программа, кажется, новая…

*** Головоломка 18. Посерьезнее. Эта — несомненно более трудная. И тоже неопубликованная. Боюсь, что вы можете избаловаться… На вход программы подается n — нечетное натуральное число.

ПРОЧЕСТЬ n.

Q := (n − 1)/4; p := целая_часть (q)

ЕСЛИ q ≠ p ТО СООБЩИТЬ 'НЕТ';

КОНЕЦ_РАБОТЫ КОНЕЦ ЕСЛИ.

ЕСЛИ нечетное p ТО СООБЩИТЬ 'НЕТ';

КОНЕЦ_РАБОТЫ КОНЕЦ_ЕСЛИ.

A := 4; b := 1.

ПОКА p ≥ a ВЫПОЛНЯТЬ.

P := p/2.

ЕСЛИ нечетное p ТО p := p − a/2 − b;

B := a − b КОНЕЦ ЕСЛИ a := a + a ВЕРНУТЬСЯ.

ЕСЛИ p = 0 ТО СООБЩИТЬ b;

КОНЕЦ РАБОТЫ КОНЕЦ_ЕСЛИ.

ЕСЛИ p + 2*b = a ТО СООБЩИТЬ a − b;

КОНЕЦ РАБОТЫ КОНЕЦ_ЕСЛИ.

ЕСЛИ p = 4 * (a − b) ТО СООБЩИТЬ 2 * a − b;

КОНЕЦ РАБОТЫ КОНЕЦ_ЕСЛИ.

СООБЩИТЬ 'НЕТ'; КОНЕЦ_РАБОТЫ.

Я не запрещаю вам перевести эту программу на ваш любимый язык, а затем испытать ее для различных значений n. Есть маленький шанс, что вы угадаете, на что она способна. Это не очевидно!

** Головоломка 19. Вклад Жака Гебенстрейта. Я обязан Жаку Гебенстрейту следующей программой. Она была предложена в том виде, в каком я ее привожу, без какого-либо комментария (это было сделано без злого умысла с его стороны: сам он получил не больше от того, кто дал ему эту программу).

ПРОЧЕСТЬ a, b; p : = max (a, b); q := min (a, b)

ПОКА q > eps ВЫПОЛНЯТЬ.

r := (q/p)²; s := r/(r + 4).

p := (2 * s + 1) * p; q := s * q.

ВЕРНУТЬСЯ.

Результат := p.

Как вам кажется, что вычисляет эта программа?