Выбрать главу

Опыт показывает, что чаще всего эта программа не останавливается.

Так как есть основное направление перемещения, подлежащее реализации (диагональ игры), то я изменил случайный выбор так, чтобы сделать более частными перемещения влево и вверх или вверх и влево.

Так как у меня еще были и другие задачи, я решил останавливать случайный выбор, когда i оказывается в маленьком прямоугольнике вверху слева. Полученный реестр (сделанный из таблицы или цепочки символов) дает тогда путь, ведущий из каждой из точек этого прямоугольника к полю прибытия.

Остальное просто.

Игра 5.

Эта игра не представляет никаких трудностей. Пусть вы не пытаетесь гарантировать Тони возможность выхода. В программе — никакой стратегии: один ход на два поля, два препятствия на горизонтальной линии на двух свободных полях (вы выбираете клетку случайным образом. Если она или ее соседка справа не свободны, то вы повторяете выбор. Если они свободны — вы их помечаете. Тем хуже для Тони, если он накрыт), два препятствия случайным образом на двух вертикальных полях.

Если вы решили оставить Тони шансы на спасение, действуйте, как в предыдущей программе. Вы случайным образом выбираете путь и обозначаете его так, чтобы никакое препятствие на него сверху не падало. Но вы не выводите на экран этих обозначений.

2. Игры с числами

Головоломка 3.

Я нашел это упражнение в монографии, посвященной языку Пролог. Предложенное там решение действует методом проб и ошибок. Но задача решается намного проще.

Как всегда, полностью определим задачу. Искомое число представляется в десятичной системе последовательностью цифр

cncn−1c25

Умножая на 5, получаем

5cncn−1c3c2

Отсюда следует, что c2 = 5. Все цифры ci точно так же итеративно вычисляются справа налево, обыгрывая оставшееся от предыдущего умножения «в уме»: когда вы умножаете крайнее справа 5 на 5, вы получаете 5 единиц, что и дает c2 = 5, и 2 «в уме». Тогда вы можете вычислить c3 и новую цифру «в уме» и продолжать шаг за шагом. Остается маленькая задача о том, как узнать, когда следует остановиться. Изучите ее сами; как обычно, я не хотел бы сообщать вам все…

Вы можете также действовать слева направо:

5cncn−1c3c2 : 5 = cncn−1c25

Деля левую цифру на 5, вы получаете cn = 1. Имея cn, вы можете продолжать деление. И здесь тоже вам нужно будет принимать во внимание перенос результата, полученного при предыдущем делении, и нужно будет знать, когда остановиться. Эти два метода по существу равносильны.

Остальное оставляю исследовать вам.

Головоломка 4.

Обычно я бываю глубоко разочарован тем, что нахожу в книгах по информатике или по математике касательно квадратных корней. Чаще всего вам предлагают метод Ньютона: пусть вам нужно извлечь квадратный корень из числа x. Вы образуете возвратную последовательность ui по правилу

ui+1 = (ui + (x/ui))/2.

Вне всякого сомнения, вы можете взять u0 = 1 в качестве начального значения. Эта последовательность очень быстро сходится к квадратному корню из x. Если, например, взять x = 50 и воспользоваться формулой

ui+1 = целая_часть ((ui + (x/ui))/2),

чтобы иметь дело только с целыми числами, то в качестве последовательных значений и вы получите

u0 = 1, u1 = 25, u2 = 13, u3 = 8, u5 = 7, u6 = 7.

Чтобы использовать здесь этот алгоритм, вы должны написать программу целочисленного деления двух целых чисел большой длины.

Другой способ действия основан на том факте, что разность двух последовательных квадратов есть нечетное число:

(n + 1)² − n² = 2n + 1,

так что последовательные разности являются последовательными нечетными числами. Поэтому можно видеть, что сумма нечетных чисел от 1 до 2k − 1 включительно есть k². Обратно, если вычитать из n последовательно возрастающие числа, пока это возможно (не допуская, чтобы результат становился отрицательным), тогда искомый квадратный корень есть к, если последнее нечетное вычитаемое равно 2k − 1. Таким образом, для 50