Учебник Информатика Алгоритмика 6 класс Звонкин Ландо Семенов

На сайте Учебники-тетради-читать.ком ученик найдет электронные учебники ФГОС и рабочие тетради в формате pdf (пдф). Данные книги можно бесплатно скачать для ознакомления, а также читать онлайн с компьютера или планшета (смартфона, телефона).
Учебник Информатика Алгоритмика 6 класс Звонкин Ландо Семенов - 2014-2015-2016-2017 год:


Читать онлайн (cкачать в формате PDF) - Щелкни!
<Вернуться> | <Пояснение: Как скачать?>

Текст из книги:
6 (О со а о -е- X IX Словарь понятий алгоритмики Алгоритм - это то же самое, что и программа. Алгоритмический язык (язык программирования) - специальный язык для записи алгоритмов. Алгоритмический язык, используемый в книге для ученика, включает в себя конструкции описания процедуры, конструкции повторения и конструкции ветвления. Ветвление - возможность исполнения разных команд в программе в зависимости от значения условия. Выигрышная стратегия - стратегия игрока, позволяющая ему выиграть при любых действиях противника. Зацикливание - бесконечное повторение одной и той же группы команд при исполнении программы. Исполнитель - устройство для выполнения определенного набора команд. Конструкция - средство для построения программы в алгоритмическом языке. В книге для ученика используются конструкции описания процедуры, повторения и ветвления. Логические значения - возможные значения условий (ИСТИНА и ЛОЖЬ). Логические операции - операции отрицания (НЕ), конъюнкции (И) и дизъюнкции (ИЛИ), позволяющие строить сложные условия из простых. Набор команд - полный список команд Исполнителя (с указанием результата выполнения каждой команды в любом возможном состоянии и ситуаций возникновения ОТКАЗа). Невозможность решения задачи - это понятие относится к задачам, не имеющим решения. Как правило, невозможность решения требует доказательства. ОТКАЗ - состояние, в котором Исполнитель не может выполнить очередную команду программы. А. к. Звонким С. К. Ландо А. Л. Семенов информатика алгоритмика Учебник для 6 класса общеобразовательных учреждений Москва «Просвещение» 2006 УДК 373.167.1:004 ББК 32.81я72 343 Авторы учебника: А. К. Звонкин, С. К. Ландо, А. Л. Семенов Автор задачника: С. К. Ландо В работе над учебником принимал участие А. X. Шень. В работе над задачником принимал участие А. Г. Кулаков. Звонкин А. К. 343 Информатика : алгоритмика : учеб, для 6 кл. общеобразоват. учреждений / А. К. Звонкин, С. К. Ландо, А. Л. Семенов. — М. : Просвещение, 2006. — 239 с. : ил. — ISBN 5-09014569-5. Основная цель учебника — научить школьников алгоритмическому мышлению: умениям предусматривать и анализировать обстоятельства, планировать свои действия. Первая часть содержит объяснительный материал, описание исполнителей, примеры решения задач. Во второй части собраны и систематизированы задачи. Учебник и задачник соответствуют федеральному учебному плану по математике и информатике. Курс рассчитан на безмашинное изучение, однако существует и распространяется программное обеспечение учебника для компьютеров IBM PC. УДК 373.167.1:004 ББК 32.81я72 ISBN 5-09-014569-5 Издательство «Просвещение», 2006 Художественное оформление. Издательство «Просвещение», 2006 Все права защищены Оглавление От авторов 6 УЧЕБНИК Глава 1. Исполнитель и его команды 1. Волк, коза и капуста с точки зрения программиста ... 8 2. Задача напоминает игру ............................ 10 3. Водолей............................................ 11 4. Удвоитель.......................................... 13 5. Кузнечик .......................................... 14 6. ОТКАЗ ............................................. 16 7. Обозначения, языки, синтаксис....................... — 8. Как облегчить себе программирование................ 20 Итоги................................................. 22 Г.'шна 2. Процедуры, или Как делать новые команды Итоги................................................. 26 Г.тнпа 3. Конструкция повторения 1. Солдаты и лодка.................................... 27 2. Новая конструкция.................................. 28 3. Зачем нужно слово КОНЕЦ в конце конструкции ПОВТОРИТЬ. Другие комментарии......................... 29 4. Использование новой конструкции. Кузнечик.......... 30 5. Использование новой конструкции. Удвоитель......... 32 6. Почему прописные (большие) буквы................... 33 7. Эффективность и сложность.......................... 34 8. Эффективный Удвоитель.............................. 35 Итоги................................................. 38 Глава 4. Условия, или Как использовать обстановку 1. Улучшенный Раздвоитель............................. 39 2. Блок-схемы ........................................ 42 3. Конструкция повторения ПОКА — ДЕЛАТЬ............... 45 4. Некоторые комментарии к конструкции ПОКА — ДЕЛАТЬ................................................ 47 Итоги................................................. 50 3 Глава 5. Робот 1. Где живет Робот................................. 51 2. Стены ........................................... — 3. Знакомство с возможностями Робота............... 53 4. Повторяющиеся мотивы............................ 59 5. Задачи потруднее ............................... 65 6. Составные условия............................... 69 7. Программы с составными условиями ............... 71 8. Пример сложной программы........................ 75 Итоги.............................................. 77 Глава 6. Чертежник 1. Точки и векторы на плоскости.................... 78 2. Команды Чертежника ............................. 79 3. Арифметические выражения........................ 82 4. Разные задачи для Чертежника.................... 84 Итоги.............................................. 92 Глава 7. Черепаха 1. Где живет Черепаха и что она может делать ...... 93 2. Повороты ....................................... 94 3. Рисуем квадрат.................................. 95 4. Что легко для Черепахи и трудно для Чертежника и наоборот ......................................... — 5. Что можно сделать из квадратов.................. 97 6. Рисуем треугольник............................. 100 7. Ленивая Черепаха помогает рисовать многоугольники и звезды.......................................... 101 8. Рисуем окружность.............................. 103 9. Другие картинки.................................. — Итоги............................................... — Глава 8. Ханойская башня 1. Правила игры .................................. 104 2. Легенда........................................ 106 3. Рекордные результаты............................. — 4. Программа..................................... 110 5. Решение задачи Брамы .......................... 112 6. Три отступления................................ 114 7. Некоторые наблюдения .......................... 115 Итоги............................................. 119 Глава 9. Невозможность Итоги.............................................. 125 4 Глава 10. Директор строительства: краткое введение в параллельное программирование Итоги.............................................. 133 Глава 11. Рекурсия 1. Процедуры, вызывающие самих себя ............... 134 2. Выход из рекурсии............................... 138 3. Когда можно обойтись без рекурсии............... 140 4. Рекурсивный вызов через промежуточную процедуру 141 Итоги.............................................. 142 ЗАДАЧНИК Справочник по алгоритмическому языку 1. Значение истинности простых и сложных условий . . . 144 2. Конструкции ...................................... — 3. Среда, системы команд и условия Исполнителей....145 A. Задачи без условий 1. Водолей......................................... 152 2. Удвоитель....................................... 155 3. Кузнечик ....................................... 157 4. Переправа....................................... 166 5. Робот............................................. — 6. Чертежник....................................... 174 7. Черепаха........................................ 189 8. Ханойская башня..................................203 9. Директор строительства...........................207 B. Задачи с условиями 10. Удвоитель/Раздвоитель ..........................211 11. Робот ..........................................214 В. Сложные задачи (проекты) 12. Удвоитель: построение оптимального алгоритма...222 13. Водолей: построение универсального алгоритма...225 14. Рекурсия. Сложные задачи для Робота ............228 15. Ханойские башни.................................231 16. Кривые дракона .................................233 17. Директор строительства: построение универсального алгоритма...........................................236 Структура задачника (послесловие для учителя)........240 От авторов Возможно, вам никогда не встречалось слово алгоритмика, и, наверное, вас заинтересует, что и почему вы будете изучать в этом курсе. Алгоритмика почти то же самое, что и программирование. Но заниматься мы будем в основном не компьютерами, а специальными способами и приемами мышления. Некоторые считают, что программирование появилось с изобретением компьютеров. Это не так. Нажимание кнопок — не главный признак программирования. Самое важное в нем — это Алгоритмическое Мышление, т. е. искусство размышлять, умение планировать свои действия, способность предусматривать различные обстоятельства и поступать соответственно с ними. Все эти умения и способности понадобились людям задолго до того, как был изготовлен первый компьютер. Само слово «алгоритм» происходит от имени средневекового ученого Мухаммеда ибн Мусы аль-Хорезми (787—850), жившего в Средней Азии. В XIII веке, когда труды аль-Хорезми были переведены с арабского языка на латынь, его имя записали так: Algorithmus. Но, конечно, люди изобретали алгоритмы и до Мухаммеда ибн Мусы. Например, все математики знают так называемый алгоритм Евклида, а Евклид жил больше двух тысяч лет назад! Главное, что отличает специалиста по программированию, — это умение ясно мыслить. Его указания должны быть настолько ясными, чтобы их мог понять даже компьютер. Вот такой ясности мысли мы с вами и будем учиться. При этом мы могли бы обойтись вообще без компьютеров. Но на самом деле компьютеры оказывают огромную помощь. Ведь они не притворяются: они действительно не понимают нечетких инструкций. Именно компьютер является окончательным судьей в том, достигли ли мы полной ясности в решении задачи, или в нем еще остались какие-то туманные моменты. И еще одна особенность отличает компьютерное мышление от человеческого. Компьютер абсолютно послушен. Часто бывает так, что вы имели в виду одно, а написали другое. Человек в этой ситуации может сам догадаться, что подразумевалось, и сделать все как надо. Компьютер так никогда не поступит. Он всегда выполнит в точности то, что ему указано, несмотря на все очевидные нелепости. Но и этим он помогает нам, так как учит правильно мыслить и четко излагать свои мысли. 6 ui ш H о c; CO >Cle учебник Глава 1 I Исполнитель и его команды Мы начнем восхождение к вершинам Алгоритмического Мышления не с микропроцессоров, чипов, клавиатуры и подобных вещей. Займемся для начала старинной русской задачей. Очень полезно посмотреть на нее с современной точки зрения. 1. Волк, коза и капуста с точки зрения программиста Вот старинная задача под названием «Волк, коза и капуста». Крестьянин стоит на левом берегу реки с волком, козой и капустой, Ему нужно перевезти все это на правый берег. Но его лодка слишком мала: он может взять только одного пассажира — либо волка, либо козу, либо капусту. И еще — если на одном берегу оставить волка и козу, то волк съест козу, а если оставить козу и капусту, то коза съест капусту. Только в присутствии крестьянина они не безобразничают. Как тут поступить? Давайте подумаем, кого перевозить первым. Ясно, что нельзя брать волка — коза останется с капустой и съест ее. По той же причине нельзя брать и капусту. Но вполне возможно забрать козу (волки обычно не любят капусту). После этого крестьянин может только вернуться в пустой лодке — везти козу назад бессмысленно. Итак, первые два шага в решении задачи такие: перевези козу переправься По команде перевези козу крестьянин перевозит козу, а по команде переправься переправляется в пустой лодке на другой берег. После этого у крестьянина есть две возможности: • перевезти волка; • перевезти капусту. 8 ГЛАВА 1 Если он перевозит волка и возвращается на левый берег, то волк и коза остаются вдвоем на правом берегу, что смертельно опасно для козы. Ну а если вместо волка он берет капусту и возвращается назад, то на правом берегу остаются коза и капуста с аналогичными последствиями для капусты. Может быть, это означает, что решения не существует? Красивая и неожиданная идея спасает ситуацию. Давайте, например, перевезем волка, но обратно отправимся не на пустой лодке, а захватим с собой козу. Дальнейшие шаги становятся очевидными. Запишем решение задачи в виде программы; перевези козу переправься перевези волка перевези козу перевези капусту ^ переправься перевези козу Упражнение Допустим, что крестьянин, перевезя на правый берег козу, взял не волка, а капусту. Напишите последовательность его действий в этом случае. Нередко при решении этой задачи появляются такие предложения: • положить капусту на спину волку (чтобы коза боялась подойти близко); • привязать волка к одному дереву, а козу к другому; • привязать капусту к лодке; • переправить козу через реку не на лодке, а на воздушном шаре; • перейти по мосту. Конечно, в условии ничего не сказано про то, что рядом есть мост. Но ведь там не говорится ни слова и о том, что моста нет! Все это так. В формулировке задачи не указано, что мы имеем право делать, а что нет. Может ли, например, крестьянин плыть за лодкой, толкая ее впереди себя? Или перебросить капусту на другой берег? Правильнее всего ответить на эти вопросы, перечислив все возможные действия крестьянина в следующем списке: перевези волка перевези капусту перевези козу переправься Допустимы только действия, перечисленные в списке; все прочие строго запрещены (или, иначе, все другие действия не имеют отношения к задаче). Исполнитель и его команды 9 Рассказанная история подводит к одному из важнейших понятий книги — Исполнителю. Исполнитель — это человек или механическое устройство (или, скажем, компьютер) со строго определенным набором возможных операций. Эти операции называются командами. Исполнитель может выполнять команды из набора, и ничего более. В задаче Крестьянин был Исполнителем, а его набор команд состоял из четырех операций. 2.| Задача напоминает игру Наш Крестьянин не похож на обычных крестьян из реальной жизни, которые могут смеяться, говорить, любить или не любить капусту. Крестьянин из задачи не способен делать ничего подобного (точнее, даже если он и умеет делать что-нибудь еще, то это нас не интересует). Все, что он может, — это выполнять четыре команды, указанные в списке возможных действий Крестьянина. Все мы оказываемся в похожей ситуации, например играя в шахматы. Шахматные правила точно говорят, что позволено делать Шахматисту. Все другие его привычки (допустим, любит ли он капусту) никак не связаны с игрой. При этом есть одно существенное различие. Шахматисту во время игры приходится принимать собственные решения. А Исполнитель не принимает никаких решений самостоятельно. Он только выполняет команды, которые мы вставляем в его программу. С этой точки зрения на Исполнителя больше всего похож не Шахматист, а Шахматный Демонстратор. Пока Шахматисты играют. Шахматный Демонстратор передвигает фигуры на большой магнитной доске, чтобы зрители могли следить за игрой. Демонстратор как будто исполняет команды, отдаваемые Шахматистами. Еще больше похожи на Исполнителя различные кнопочные устройства. Представьте себе маленькое устройство, подобное электронной игре. На экране вы видите волка, козу, капусту и Крестьянина с лодкой. Рядом с экраном четыре кнопки. На первой надпись перевези волка, на второй — перевези козу и т. д. Нажимая на кнопки, мы передвигаем наших героев по экрану. Других путей управления ими нет. Написать программу означает задать порядок, в котором нажимаются кнопки. Задачу о Крестьянине мы можем тоже считать игрой. И, составляя список команд, мы всего лишь уточняем правила игры. А можно представлять себе устройство с кнопками, и тогда список команд — набор кнопок. В этой книге вы встретитесь с несколькими Исполнителями и некоторыми играми. 10 3^ Водолей Вам нужны новые примеры Исполнителей? Вот один из них. Мы назвали его Водолеем, потому что он занят переливанием воды. Трудно ли отмерить литр воды? Ответ зависит от того, какие имеются емкости. Если есть литровая банка А, то программа будет состоять из одного шага: наполни А Немного усложним задание. Представим себе, что у нас есть две емкости: двухлитровая банка А и трехлитровая банка В. Тогда решение задачи состоит из двух шагов: наполни В перелей из В в А После первого шага в банке В будет 3 литра воды, а на втором шаге выливаем 2 литра воды из В в А, после чего в В остается 1 литр воды. Задача 1.1 Отмерьте 1 литр воды с помош;ью одной 3-литровой банки и одной 5-литровой банки. Дадим теперь более строгое описание Водолея и его команд. Прежде всего у него должен быть источник воды: река, озеро или бассейн, количество воды в котором не ограничено. Затем мы должны зафиксировать число емкостей (ведер, банок и пр.) и величину каждой из них. Обозначим емкости буквами А, В, С, ... . Команды Водолея бывают трех видов. Первый вид: наполни А (или В, С, ...) В результате выполнения этой команды соответствуюш;ая емкость наполняется до краев. Команд такого вида столько же, сколько емкостей. Второй вид: вылей из А (или В, С, ...) И с п о л н егс команды 11 ь в результате выполнения этой команды соответствующая емкость становится пустой. Число таких команд также равно числу емкостей. Третий вид: перелей из А в В (или из А в С и т. д.) Результат этой команды зависит от того, достаточно ли в емкости В места для всей воды из емкости А. Если да, то емкость А становится пустой, а в В оказывается столько воды, сколько было в А и В вместе до переливания. Если же места в В недостаточно, то В становится полной, а в А остается столько воды, сколько не поместилось в В. Число команд третьего вида равно числу пар емкостей. Выпишем все команды Водолея с двумя емкостями, например с ведрами: наполни А вылей из В наполни В вылей из А перелей из А в В перелей из В в А Если ведер три, то общее число команд равно 3 + 3-Ь6 = 12. Упражнение Напишите полный список команд для Водолея с тремя ведрами А, В, С. Обычно в начале каждой задачи все емкости пусты. Наша цель — получить (отмерить) требуемое количество воды в одной из емкостей, причем неважно, в какой именно и сколько воды будет при этом в остальных емкостях. Задача 1.2 Имеются 5-литровая емкость А и 8-литровая емкость В. а) Отмерьте 1 литр воды. б) Отмерьте 4 литра воды. Водолей — не один Исполнитель, а много Исполнителей с похожими правилами. Чтобы выделить любого из них, нужно зафиксировать величины емкостей. А чтобы поставить задачу, надо сказать, сколько воды вы хотите отмерить. Упражнение 1) Обдумайте свой собственный вариант Водолея. 2) Придумайте задачу для него. 3) Поделитесь своей задачей с классом. 12 ГЛАВА 1 4. Удвоитель Удвоитель — воображаемое устройство с экраном и двумя кнопками. На экране отображается число. В момент включения Удвоителя оно равно 0. На клавишах написано прибавь 1 и умножь на 2. При нажатии на первую клавишу число, изображенное на экране, увеличивается на 1, а при нажатии на вторую клавишу удваивается. Если, например, на экране было число 7 и мы нажали клавишу прибавь 1, то число 7 пропадает, а вместо него появляется число 8. Если же нажать клавишу умножь на 2, то вместо числа 7 появится число 14. В нашем представлении Удвоитель является Исполнителем с двумя командами: прибавь 1 и умножь на 2 Давайте получим на экране число 17. (Начнем с 0.) Вот две возможные программы, выполняющие это задание: прибавь 1 I прибавь 1 ' прибавь 1 ' прибавь 1 , прибавь 1 ) прибавь 1 ' прибавь 1 ' прибавь 1 ' прибавь 1 ; прибавь 1 ; прибавь 1 прибавь 1 прибавь 1 прибавь 1 прибавь 1 прибавь 1 ' прибавь 1 прибавь 1 умножь на умножь на умножь на умножь на прибавь 1 t -J Какая из этих программ вам больше нравится? Почему? Упражнение Придумайте еще какую-нибудь программу для получения числа 17. Какое количество команд может иметь такая программа, если: а) первая команда в ней — прибавь 1; б) если первая команда может быть любой? Р1 ель и его команды 13 н Задача 1.3 Можно ли получить на экране любое положительное целое число? Поясните свой ответ. Устройте соревнование: кто-нибудь называет число и все пытаются его получить. Выигрывает тот, кто напишет программу с наименьшим числом шагов (команд). Задача 1.4 а) Получите число 15 меньше чем за 8 шагов. б) Получите число 1024. в) На экране написано число 4. Получите из него число 15 меньше чем за 6 шагов. 5. Кузнечик Нарисуем горизонтальную прямую и нанесем на нее квадратные метки на равном расстоянии друг от друга (рис. 1.1). Метки отмечают точки на прямой. Одну из точек обозначим числом 0. Точки справа от нее обозначим числами 1, 2, 3, 4, ... , а точки слева — числами -1, -2, -3, -4, ... . Стрелка на прямой указывает направление, в котором увеличиваются числа. Такую прямую будем называть числовой осью. На числовой оси живет Исполнитель Кузнечик. На рисунке 1.1 (и далее) он обозначен буквой оК». К Рис. 1.1 -^-О--2 -1 £>-СН1Ь-П о 1 2 3 4 ■О 5 6 В начальный момент Кузнечик находится в точке 0 числовой оси. Он может прыгать на 3 единицы вперед (рис. 1.2) и на 2 единицы назад (рис. 1.3). Таким образом, список его команд содержит только две строчки: вперед 3 и назад 2 Рис. 1.2 -2 -1 0 1 2 3 4 5 6 К -снп-сь- Рис. 1.3 -2 -1 0 1 2 3 4 5 6 14 ГЛАВА I Рис. 1.4 2 1 О 1 2 3 4 5 6 Дуги со стрелками показывают, из какой точки в какую прыгает Кузнечик при выполнении команд. На рисунке 1.4 показано, как прыгал Кузнечик, выполняя такую программу: вперед 3 | вперед 3 j назад 2 назад 2 , назад 2 l Упражнение Задача 1.5 Связана ли Задача 1.6 Задача 1.7 Задача 1.8 Задача 1.9 1) Переведите Кузнечика из точки О в точку 7. 2) Переведите Кузнечика из точки О в точку 2. У Кости есть только монеты достоинством 3 копа, а у Димы — только 2-коповые. Костя должен Диме 7 копов. Как ему расплатиться? эта задача как-нибудь с Кузнечиком? Заставьте Кузнечика побывать по одному разу в каждой из точек 1, 2, 3, 4, 5, не выходя за пределы отрезка от О до 5. Кузнечик начал выполнение программы в точке О и закончил в точке 2. Затем программа была выполнена еще раз. Где теперь оказался Кузнечик? Может ли Кузнечик добраться до любой точки на прямой? Как? Поменяем список команд Кузнечика. Изменение списка команд, даже самое маленькое, означает, что мы получили другого Исполнителя. Но мы все равно будем называть его Кузнечиком. Новый список для этого Кузнечика состоит также из двух комгшд: вперед 7 и назад 5 Может ли новый Кузнечик добраться до любой точки прямой, например до точки 1? Исполнитель и его команды 15 Как вы уже заметили, у нас было много разных Водолеев, отличающихся числом емкостей и их объемами. Точно так же нам придется иметь дело с различными Кузнечиками: они будут совершать разные прыжки вперед и назад. ^ ОТКАЗ Не всякую команду можно исполнить в любой ситуации. Для того чтобы команда была выполнима, нужны особые условия. Представим себе, что программа для Крестьянина начинается со строчек перевези козу перевези волка Но на правом берегу еще нет волка, поэтому перевезти его через реку невозможно. В таком случае выполнение программы останавливается. Эту невозможность выполнить команду мы называем ОТКАЗ. Если в процессе выполнения программы возникает ОТКАЗ, то это означает, что программа работает неправильно и не достигает своей цели — Исполнитель ломается и выходит из строя. Программу, допускающую возникновение ОТКАЗа, следует исправить. Та же ситуация возникает и при игре в шахматы, когда мы указываем какой-нибудь фигуре перейти с одного поля на другое, а на первом поле этой фигуры нет. ОТКАЗ другого рода происходит, когда волк остается с козой без Крестьянина: такое положение противоречит условиям игры. В шахматах то же самое случается, если, например, король не уходит из-под шаха. 7. Обозначения, языки, синтаксис Искусство придумывать удобные обозначения играет важную роль в человеческой культуре. Возьмем, например, обозначения чисел. Все вы умеете складывать и умножать числа в столбик. Десятичная система обозначений делает это возможным. А попробуйте сложить числа, записанные римскими цифрами. Вы увидите, что обозначения никак не помогают вам в этой задаче. Или возьмем музыку. Придумав ноты для обозначения музыкальных звуков, музыканты получили возможность записывать и распространять более сложную и интересную музыку. Существует еще много подобных примеров. 16 ГЛАВА 1 в алгоритмике удобные обозначения играют более важную роль. Есть в ней и особенности. Некоторые вопросы мы обсудим. 1. Одну и ту же мысль можно по-разному выразить словами. Мы можем написать перевези козу или перевези козу через реку или даже посади козу в лодку и перевези ее на другой берег Любой способ годится. Нужно только выбрать какой-то один, остановиться на нем и уже не менять его. 2. Записывать команды очень длинными фразами, как в последнем примере, неудобно. Уж слишком долгим и занудным делом станет тогда составление программ. Лучше придумывать более короткие обозначения. Но и краткостью не надо чрезмерно увлекаться. Чересчур короткие обозначения могут быть непонятными. Предположим, что мы стали бы писать пк вместо перевези козу, пкп вместо перевези капусту и т. д. Читать и понимать такую программу было бы нелегко. Везде нужен разумный компромисс. 3. Представьте себе, что какой-то программист приготовил для вас специальную компьютерную программу. Крестьянин, волк и все остальные — это картинки на экране. Вы можете управлять ими, вводя команды с клавиатуры. Программа прочитывает тот текст, который вы ввели, и сравнивает с имеющимися у нее образцами. Допустим, вы ввели строчку из тринадцати символов (считая пробел): перевези козу В этом случае Крестьянин на экране перевезет козу на другой берег. Теперь вместо этого вы ввели другие четырнадцать символов: перевези волка Крестьянин перевезет волка, а коза тем временем съест капусту. Предположим далее, что вы напишете перевези козу на правый берег или осторожно перевези козу И с п (^го команды 17 или ладно, начнем с козы Что же произойдет при этом? Конечно, ответ зависит от устройства конкретной программы. Но почти наверняка она просто не поймет того, что вы написали. Для нее такая последовательность символов не имеет никакого смысла. Программа может понять только то, что заранее предусмотрел программист. А он не может предусмотреть все на свете. Вот почему в алгоритмике так важно всегда придерживаться одних и тех же обозначений. Требование понятности для компьютера иногда приводит к довольно странным результатам. Так, некоторые компьютерные системы анализируют отдельно каждое слово между пробелами. Для них команда не может состоять из двух слов, а то компьютер решит, что это две разные команды. В таких системах можно встретить обозначения вида перевезикозу или ПеревезиКозу или перевези_козу Вы заметили — мы всеми средствами избегаем пробела внутри команды! Так что если вы встретите где-нибудь такие странные обозначения, то не удивляйтесь. Знайте, они вызваны чисто техническими причинами. Так удобнее для компьютера. 4. Команды, даваемые Исполнителю, должны быть абсолютно ясными. Они не должны допускать двусмысленностей. Обычный человеческий язык очень выразителен, но часто неоднозначен. Иногда одно и то же слово может иметь два разных смысла, а подчас двусмысленность прячется в самой фразе. Посмотрим, например, на такую задачу-шутку: На ветке сидело семь птиц. Охотник выстрелил и трех птиц убил. Сколько птиц осталось? Слову «осталось» можно придать два разных смысла. Первый — естественный — «осталось в живых». Второй — шуточный — «осталось на месте» (остальные улетели). В первом случае ответ 4, а во втором — 3. Так как в задаче сказано, что это шутка, то правильным оказывается второй ответ. Но компьютер-то шуток не понимает! Решить такую задачу ему не под силу. В алгоритмике предпринимаются специальные усилия, чтобы избежать подобных ситуаций. 5. Вот красивая древняя легенда. Человек, который ее придумал, наверняка был в душе программистом. Однажды бог Дионис предложил царю Мидасу исполнить любое его пожелание. Мидас пожелал, чтобы все, к чему он прикасался, превращалось в золото. Уже через несколько минут он стал самым 18 богатым человеком на свете. Вскоре, однако, возникло неожиданное затруднение: еда и питье царя Мидаса также превращались в золото. Царю грозила голодная смерть! Хорошо, что Дионис сжалился над ним и избавил его от своего дара. Как видите, точность формулировок нужна не только при работе с компьютером. Конечно, Мидас, высказывая свое пожелание, не имел в виду, что еда и питье тоже должны превращаться в золото. Возможно, подумав, он захотел бы сделать и еще какие-нибудь исключения. Но беда в том, что Мидас не сформулировал их в явном виде. Он только подразумевал их, считая, что все и так понятно. Люди, пищущие программы, часто оказываются в сходной ситуации. 6. Точность и ясность важны во многих областях человеческой деятельности. Например, при составлении законов. Инструкции по управлению атомной электростанцией или ракетной установкой с ядерными боеголовками не должны содержать неясностей, темных мест и двусмысленностей. От этого зависит безопасность всей планеты! Во всех делах, связанных с законами и инструкциями, необходимо развитое Алгоритмическое Мышление. Впрочем, существует и иная точка зрения. Зачем нужен человек, сидящий при атомной бомбе, если вся его задача — точное выполнение инструкций? Казалось бы, его вполне можно заменить компьютером. Тем не менее мы поручаем это человеку. Человек не является Исполнителем: он не только исполняет приказы, но и принимает самостоятельные решения, берет на себя ответственность. Видимо, в глубине души мы надеемся, что, когда инструкция потребует нажать кнопку и начать атомную войну, человек возьмет ответственность на себя и нарушит инструкцию. 7. В некоторых профессиях точное понимание указаний необходимо каждый день и каждую минуту. Это относится, например, к обмену сообщениями между пилотом самолета и диспетчером аэропорта. Если диспетчер будет изъясняться длинными запутанными фразами и жестами, то пилот (который его к тому же не видит) собьется с пути и разобьет самолет. В этой ситуации люди придумали такой выход. Они заранее составили список очень простых, даже примитивных фраз и, подробно и четко договорившись, что каждая фраза означает, переговариваются между собой только с помощью этих фраз, без всяких излишеств. Очень похоже на команды для Исполнителей, не правда ли? А со стороны может показаться, что они говорят на каком-то своем, только им понятном языке. 8. Создатели компьютеров пошли по тому же пути. Для общения с компьютерами они создают специальные языки, которые называются языками программирования. Широко известны такие из них, как Fortran, PL/I, Algol, Lisp, Logo, Basic, C, Ada, Pascal и многие другие. Сейчас существует уже несколько тысяч языков программирования. Для обучения вас алгоритмике мы тоже 19 придумали специальный язык, похожий на многие уже известные и отражающий их общие черты. Вы должны понимать, как и почему языки программирования стали такими. Поэтому в учебнике мы заново пройдем путь изобретения языка с вами вместе. А по дороге постараемся объяснить причины принятых нами решений. Мы уже начали все это делать. 9. Все языки имеют правила, устанавливающие, что и как можно писать. Эти правила называются синтаксисом. Вводя новые правила, мы будем стараться объяснять вам их смысл и цель. Но сделать это не всегда легко. Вот простое синтаксическое правило, которого мы придерживались, но еще не формулировали явно: СИНТАКСИЧЕСКОЕ ПРАВИЛО • Каждая команда в программе записывается в отдельной . строке. Наверное, вы обратили внимгшие и на то, что команды исполнителей записываются строчными (маленькими) буквами. В дальнейшем мы будем придерживаться и этого правила, позволяя себе, однако, от него иногда отступать. 8. Как облегчить себе программирование Вернемся к задаче о Водолее из раздела 3. У нас имеются 5-литровая емкость А и 8-литровая емкость В; нужно отмерить 4 литра воды. Решение задачи можно записать в виде программы. Понятно, что здесь написано? Нам кажется, что нет. Мы сами не понимаем, хотя в программе всего 10 команд. А что, если в программе их будет тысяча? Конечно, мы заблудимся в них и потонем во всей этой переливающейся воде. Но как сказано в известном романе И. Ильфа и Е. Петрова «Двенадцать стульев*: «Спасение утопающих — дело рук самих утопающих*. И если мы хотим облегчить себе написание программы и удостовериться в том, что она работает правильно, то нам нужен инструмент для ее проверки — щаг за шагом от начала до конца. К счастью, ясно, что это за инструмент. Быть может, вы изобрели его самостоятельно до того, как начали читать этот параграф. наполни А перелей из А в В наполни А перелей из А в В вылей из В перелей из А в В наполни А перелей из А в В наполни А перелей из А в В 20 ГЛАВА 1 Нам всего лишь нужно записывать состояния всех объектов до и после выполнения каждой команды. В нашем случае это просто количество воды в каждой емкости. Составим такую табличку: Команда А [5 л] В [8 л] 0 0 наполни А 5 0 перелей из А в В 0 5 наполни А 5 5 перелей из А в В 2 8 вылей из В 2 0 перелей из А в В 0 2 наполни А 5 2 перелей из А в В 0 7 наполни А 5 7 перелей из А в В 4 8 Окончательное состояние: в емкости А 4 литра воды. Теперь легко проверить каждую команду отдельно и независимо от всех остальных. Проверим, например, 4-ю команду. Перед ее выполнением в обеих емкостях по 5 литров воды; это означает, что емкость А полная, а в емкости В 3 литра пустого объема. Следовательно, из А в В мы переливаем 3 литра воды, в А остается 2 литра, а емкость В заполняется (т. е. в ней 8 литров воды). Упражнение Задача 1.10 Проверьте все шаги программы. Три рыцаря с тремя оруженосцами подошли к реке. Они нашли маленькую лодку, в которой через реку могут переехать только два человека. Каждый оруженосец так предан своему хозяину, что он отказывается оставаться на берегу или в лодке с другими рыцарями в отсутствие хозяина. (Но он готов быть один или с другими оруженосцами.) Как они вшестером могут переправиться через реку? Придумайте систему команд для Исполнителя в данной задаче. Напишите в этой системе команд программу, решающую поставленную задачу. Нарисуйте таблицу состояний при исполнении программы и заполните ее. Исполнитель и его команды 21 Напомним, что надо соблюдать три правила: • в лодке могут находиться не больше двух человек; • в лодке не может оказаться оруженосец с чужим рыцарем; ' если на берегу вместе с оруженосцем есть чужой рыцарь, то должен быть и его (оруженосца) рыцарь. Для проверки соблюдения первых двух правил достаточно просмотреть саму программу. Но чтобы убедиться, что не нарушено последнее правило, нужна таблица. Профессиональные программисты при написании программ вставляют в них утверждения о состоянии программы. Они помогают программисту удостовериться в том, что программа работает как положено, и позволяют доказывать правильность программы. Иногда это кажется обременительным. (Любая дисциплина обременительна, не правда ли?) Но у программистов очень уважаемая работа. В наши дни компьютеры управляют самолетами и атомными электростанциями, помогают врачам при хирургических операциях, выполняют много других важных дел. Нужно быть твердо уверенными в том, что программы работают правильно. И один из самых могуш;ественных способов достижения такой уверенности — дисциплина программирования. Множество примеров этого встретится нам на страницах книги. ИТОГИ в этой главе вы впервые встретились с основными понятиями Алгоритмического Мышления: Исполнитель; команды, которые может выполнять Исполнитель: полный список команд; простая программа (последовательность команд); ОТКАЗ (невозможность выполнить команду); дисциплина программирования (способ облегчить себе написание программы). В следующих главах вы: встретите новых замечательных Исполнителей с простыми командами, но интригующим поведением; узнаете, как проверять условия и заставлять Исполнителя действовать в соответствии с ними; познакомитесь с основными конструкциями программирования (выбор, повторение и вызов процедуры), которые позволяют конструировать сложные программы из простых. L J . Глава 2 J-. f I ’яимамййя*» •<^*1чи.ггп*-«'«4'г7мг^ i Процедуры, или Как делать новые команды Эта глава совсем короткая, но очень важная. Мы покажем, как обучать Исполнителя некоторым новым командам. Новые команды мы составим из уже имеющихся команд. Одна из основных частей Алгоритмического Мышления — искусство записи. Мы понимаем под этим искусство записывать сложный набор инструкций в простой и понятной форме. Для упрощения записи служат различные конструкции. Эти конструкции присущи большинству языков программирования. Они обеспечивают возможность: создавать новые команды на основе имеющихся команд; • повторять некоторые команды по несколько раз; • проверять условия и действовать в зависимости от результатов проверки. А теперь познакомимся с первым элементом этого списка. Всякую программу можно преобразовать в новую команду. Для этого к ней необходимо добавить очень простую вещь — имя. Действительно, если мы хотим исполнить команду, то ее нужно как-то вызвать, т. е. обратиться к ней по имени. Чтобы отличить новые команды от старых, назовем их процедурами. Итак, процедура — это программа с именем Всякий акт наименования должен сопровождаться специальной церемонией. Для нас церемония будет заключаться в особом соглашении о том, как записывать процедуры. В этой книге мы пользуемся таким способом: ПРОЦ <имя новой команды (процедуры)> I НАЧАЛО <программа, описывающая, что делает процедура> . КОНЕЦ , Процедур! К 1 ( Д е I' I i ь м :j I 23 ПРОЦ перевези вкк НАЧАЛО перевези козу переправься перевези волка перевези козу перевези капусту переправься перевези козу КОНЕЦ Проиллюстрируем эту схему несколькими примерами. 1. Мы уже написали программу для перевозки волка, козы и капусты через реку. Придумаем имя для этой программы, например перевези вкк. Теперь записать процедуру легче легкого (см. справа). После того как эта церемония проведена, мы можем просто выполнить команду перевези вкк, что приведет к выполнению всех семи простых команд, записанных между словами НАЧАЛО и КОНЕЦ. Упражнение Выполнена следующая программа; ’ перевези вкк \ перевези вкк перевези вкк Что при этом произошло? Ответ Крестьянин перевез волка, козу и капусту с левого берега на правый; сразу же после этого он начал перевозить их с правого берега на левый в том же порядке. Закончив эту работу. Крестьянин снова переправил их с левого берега на правый. 2. Рассмотрим Кузнечика с двумя простыми командами: вперед 7 назад 5 Сделаем новую команду один шаг вперед: ПРОЦ один шаг вперед НАЧАЛО вперед 7 вперед 7 вперед 7 назад 5 назад 5 назад 5 назад 5 КОНЕЦ 24 ГЛАВА 2 Проверьте, что все правильно! Имея новую команду, легко, например, перейти из О в 3: один шаг вперед один шаг вперед один шаг вперед Или перейти из О в 10: вперед 7 один шаг вперед ' один шаг вперед один шаг вперед ‘ Мы видим, что процедуры можно вызывать в программе наравне с обычными командами Исполнителя. Мы можем использовать процедуры и для определения других процедур: ПРОЦ вперед на 16 ' НАЧАЛО вперед 7 один шаг вперед \ вперед 7 ' один шаг вперед КОНЕЦ ______ Новой процедурой вперед на 16 можно пользоваться так же, как прочими командами и процедурами. СИНТАКСИЧЕСКИЕ ПРАВИЛА Слова ПРОЦ, НАЧАЛО и КОНЕЦ пишутся прописными (большими) буквами. Эти слова должны быть написаны на разных строках стро- . го одно под другим. ’ Имя процедуры записывается после слова ПРОЦ в той же j строке. I Текст процедуры записывается между словами НАЧАЛО и ! КОНЕЦ с некоторым сдвигом вправо. Как и имена команд Исполнителей, имена процедур будем записывать, как правило, строчными (маленькими) буквами. дела ь новые команды 25 Комментарий 1 Синтаксические правила имеются во всех языках программирования. Они могут очень сильно отличаться друг от друга, как в языках Pascal, Basic, Logo. Здесь мы описываем правила нашего языка. Комментарий 2 Записывая процедуру, мы придумываем для нее имя. Мы свободны в выборе имени. Но этой свободой следует пользоваться разумно. Так, например, процедуру для Кузнечика мы назвали один шаг вперед. Мы могли бы дать ей имя андрей, ааа или даже т21мал543. Синтаксические правила этого не запрещают. Представьте себе, однако, что через несколько месяцев, просматривая старую программу, вы наткнетесь на команду т21мал543. Сколько уйдет у вас времени на то, чтобы понять, что делает эта команда? А если это будете не вы, а кто-нибудь другой? Поэтому руководствуйтесь следующим советом. Имя, которое вы даете процедуре, должно кратко пояснять ее назначение. Задача 2.1 а) Составьте процедуру один шаг назад, переводящую Кузнечика на единицу влево. Проверьте правильность ее работы. б) Напишите программу перехода из О в 6. в) Каким будет результат выполнения программы один шаг вперед один шаг назад * ИТОГИ у любого Исполнителя есть набор начальных простых команд. Про каждую команду мы должны знать, как она работает в любой ситуации. Список команд и определяет Исполнителя. Этот список строго ограничен. Изменить его означает изменить Исполнителя. Новые команды, или процедуры, конструируются из простых команд. Новых процедур можно придумать сколько угодно. 17 РАЗ Глава 3 ( p-|-:’_ ■■■^ -[I'r ‘I ■' Конструкция повторения _J_ 1. Солдаты и лодка Рассмотрим задачу о 60 солдатах. К реке подошли шестьдесят солдат. Им нужно переправиться через реку. Рядом с берегом плавают два мальчика в лодке. Но лодка такая маленькая, что она может поднять только двух мальчиков или одного солдата. Как солдатам переправиться через реку и вернуть лодку мальчикам? Сразу видно, что без помощи мальчиков солдатам не обойтись: солдату, переправившемуся через реку, нужно возвращаться обратно, чтобы вернуть лодку для следующей переправы. Выпишем все команды, просто указывая, кто переправляется через реку. Итак, у нас имеется ровно три команды: солдат мальчик два мальчика А теперь забудем для простоты о 59 солдатах и решим нашу задачу только для одного солдата. И будем помнить, что мальчики должны получить лодку обратно! Это и честно, и необходимо, чтобы следующий солдат тоже смог переправиться. Вот решение: два мальчика мальчик солдат мальчик Хотите убедиться в этом? Хорошо, составим вспомогательную таблицу, как в предыдущей главе: Конструкция повторения 27 Команда Левый берег Правый берег два мальчика, солдат, лодка два мальчика солдат два мальчика, лодка мальчик мальчик, солдат, лодка мальчик солдат мальчик мальчик, солдат, лодка мальчик два мальчика, лодка солдат Готово! А теперь, когда задача о переправе одного солдата решена, совсем нетрудно найти решение и главной задачи. Нужно лишь повторить ту же последовательность команд 60 раз. Можете начать прямо сейчас, часа вам наверняка хватит, чтобы закончить работу. А когда вы это проделаете (и если в тетради еще останется свободное место), запишите решение той же задачи, но уже для шестисот солдат. Конечно, вы уже догадались, что мы просто шутим! 2. Новая конструкция Одно из достоинств компьютеров состоит в том, что они могут исполнять миллионы и миллиарды вычислительных операций за короткое время, в частности, миллионы раз повторять одну и ту же последовательность действий. Но было бы чудовищно, если бы программист был вынужден повторять в программе миллион раз одну и ту же последовательность команд. На самом деле во всех языках программирования есть средства, позволяющие указывать, что какая-то последовательность команд должна быть выполнена несколько раз. Мы для себя изобретаем обозначения сами, поэтому введем новую конструкцию ПОВТОРИТЬ <число> РАЗ <команды, которые необходимо повторить> КОНЕЦ Вместо слова <число> мы подставляем какое-нибудь конкретное число, например 30, или 77, или 189. Смысл конструкции состоит в том, что все команды, записываемые между ПОВТОРИТЬ 30 РАЗ и КОНЕЦ, должны быть повторены 30 раз. Вот так! 28 ГЛАВА 3 Теперь для записи решения задачи о 60 солдатах (см. справа) нам нужно гораздо меньше бумаги и времени, чем раньше. И если какому-нибудь шутнику придет в голову попросить вас написать программу не для шестидесяти, а для шестисот солдат, то это вас не испугает. Вы просто замените строку ПОВТОРИТЬ 60 РАЗ на строку ПОВТОРИТЬ 600 РАЗ — и все! ПОВТОРИТЬ 60 РАЗ два мальчика мальчик солдат мальчик КОНЕЦ ^ Зачем нужно слово КОНЕЦ в конце конструкции ПОВТОРИТЬ. Другие комментарии Посмотрим внимательнее на конструкцию ПОВТОРИТЬ <число> РАЗ ' < команды > ' КОНЕЦ ^ Вам может показаться, что в последнем слове КОНЕЦ нет необходимости. Но это не так. В более сложных программах нам потребуется одни команды повторять, а другие нет. Как отличить их друг от друга? Пусть, например, в дополнение к трем приведенным выше командам наш список содержит четвертую команду: победный танец По окончании своей трудной работы ребята могут захотеть сплясать победный танец. Предположим, что мы просто запишем ПОВТОРИТЬ 60 РАЗ два мальчика мальчик солдат мальчик победный танец Но при этом невозможно понять, сколько раз будут мальчики тгш-цевать — 1 раз или 60 (т. е. каждый раз, получая назад свою лодку). !<онстр кция повторения 29 теперь напишем ПОВТОРИТЬ 60 РАЗ * два мальчика I мальчик < , солдат ' ' мальчик I КОНЕЦ 1 победный танец « Так все станет на свои места. Команды, стояш;ие между словами ПОВТОРИТЬ и КОНЕЦ, повторяются 60 раз, а остальные нет. СИНТАКСИЧЕСКИЕ ПРАВИЛА • Слово КОНЕЦ мы пишем в точности под словом ПОВТОРИТЬ, а все команды между ними сдвигаем вправо. Так легче читать написанную программу. • Слова ПОВТОРИТЬ, РАЗ и КОНЕЦ мы пишем прописными буквами, а все остальные слова (команды) — строчными. Причину этого мы обсудим позднее. 4^ Использование новой конструкции. I Кузнечик с помош;ью введенной конструкции мы можем гораздо проще записать решения многих задач. Начнем с Кузнечика, исполняющего две команды (см. главу 1, раздел 5): вперед 3 назад 2 Задача 3.1 Кузнечику надо добраться от точки 0 до точки 360. Ответ ПОВТОРИТЬ 120 РАЗ вперед 3 КОНЕЦ Следующая задача труднее. Задача 3.2 Кузнечик стоит в точке 0. Заставьте его побывать в каждой точке от 1 до 100, причем по одному разу. 30 вперед 3 назад 2 вперед 3 назад 2 вперед 3 Подсказка Похожая задача у нас уже была — ■ главу 1, раздел 5, задача 1.6) — тот Кузнечик должен был побывать по одному разу в каждой точке от 1 до 5. Задача решалась так ( нп*»пеп Я I (см. справа): Наш Кузнечик находится в точке 5. И он не выходил за пределы отрезка от О до 5. Если повторить снова ту же самую последовательность комгшд, то Кузнечик побывает, причем только по одному разу, в точках 6, 7, 8, 9, 10 (проверьте это!). Теперь решение очевидно. Решение Сделаем нашу первую программу процедурой: ПРОЦ обойди пять ; НАЧАЛО вперед 3 назад 2 ; вперед 3 назад 2 вперед 3 I КОНЕЦ И окончательная программа становится совсем простой: ПОВТОРИТЬ 20 РАЗ обойди пять КОНЕЦ Вернемся к задаче 1.9. В ней речь идет о Кузнечике с двумя командами: вперед 7 и назад 5 Может ли он добраться до любой точки прямой? От^т Да. Чтобы убедиться в этом, вспомним процедуру из главы 2 один шаг вперед. Последовательно повторяя эту процедуру столько раз, сколько хотим, мы будем получать точки 2, 3, 4, ... . Поэтому если нам нужно добраться, например, до точки 72, то мы можем написать такую программу: ГпОВТОРИТЬ 72 РАЗ один шаг вперед КОНЕЦ Конструкция повторения 31 Достоинство этой программы в том, что она дает общий способ решения любой такой задачи. Если, скажем, вместо точки 72 нам понадобится точка 216, то мы просто заменим в программе 72 на 216, и задача будет решена. Такую программу называют общей. Но у этой программы есть и недостаток — она требует слишком большого числа прыжков. Сравним ее с другой программой, которая тоже переводит Кузнечика в точку 72 (см. слева). ПОВТОРИТЬ 11 РАЗ 1 вперед 7 I КОНЕЦ назад 5 Упражнение Задача 3.3 Подсчитайте количество прыжков в каждой программе и сравните эти числа. Напишите программу, переводящую Кузнечика в точку 216, число прыжков для которой было бы наименьшим. Постарайтесь доказать, что число прыжков в вашей программе действительно наименьшее. 5. Использование новой конструкции. Удвоитель Перепишем для начала уже известные нам две программы из пункта 4 главы 1. Обе они получают из О число 17. Первая программа: Вторая программа: ПОВТОРИТЬ 17 РАЗ прибавь 1 КОНЕЦ прибавь 1 ПОВТОРИТЬ 4 РАЗ умножь на 2 КОНЕЦ прибавь 1 Первая программа оказывается довольно простой. Она к тому же еще и общая: вместо числа 17 можно задать любое другое число, и мы получим его в результате работы программы. Но она неэффективна. Ей требуется 17 шагов, а второй программе — всего 6. Упражнения Сравним две программы получения числа 1024 из 0. i ПОВТОРИТЬ 1024 РАЗ > прибавь 1 1 КОНЕЦ , прибавь 1 t ПОВТОРИТЬ 10 РАЗ I умножь на 2 [ КОНЕЦ г 32 ГЛАВА 3 1) Проверьте, что в результате работы второй программы получается число 1024. 2) Сосчитайте число шагов в обеих программах. А теперь представьте себе, что программу должны выполнить вы: перед вами автоматическое устройство, на экране которого пишется число, и две кнопки — 1 и 2. Нажатие на кнопку 1 прибавляет 1 к числу на экране; нажатие на кнопку 2 умножает его на 2. Сначала на экране 0, а вы хотите получить 1024. Какую программу предпочтете вы лично: первую или вторую? Задача 3.4 Получите из 0 число 729 не более чем за 30 шагов. Теперь у нас есть три темы для разговора: • Почему слова ПОВТОРИТЬ, РАЗ и КОНЕЦ мы пишем прописными буквами? • Как измерить качество программ: простые они или сложные, эффективные или нет и т. д.? • Как писать эффективные программы для Удвоителя? Обсудим их по очереди. ^ Почему прописные (большие) буквы Пока нам встречалось мало Исполнителей. Но в последующих главах их появится очень много. И конечно, можно придумать огромное количество Исполнителей, которых в книге нет. У каждого Исполнителя свой собственный набор команд (или правил). Но конструкция повторения ПОВТОРИТЬ <число> РАЗ - <команды, которые необходимо повторить> КОНЕЦ одинакова для всех. Она не зависит от того, с каким Исполнителем мы имеем дело, и подходит каждому из них. Она универсальна — ее можно использовать в программах для любого Исполнителя. Эта конструкция — одна из основных в программировании. Исполнителей сотни и тысячи. Но таких универсальных конструкций, как ПОВТОРИТЬ - РАЗ, совсем немного — и это фундаментальное свойство программирования. Основных конструкций всего три. Иногда для удобства используется несколько дополнительных конструкций. Вы не слишком ошибетесь, если решите, что главная цель нашей книги — обучение искусству пользоваться 33 ими. Ключ к Алгоритмическому Мышлению и программированию — это свободное владение универсальными конструкциями. Чтобы отличать универсальные конструкции от команд Исполнителей по внешнему виду, мы записываем их прописными буквами. 7. Эффективность и сложность Мы уже обсуждали эффективность различных программ. Шаг исполнения программы — это выполнение Исполнителем одной команды. Из двух программ, решаюш;их одну и ту же задачу, более эффективна та, которая требует при исполнении меньше шагов. Мера эффективности — это просто число шагов. Но при более внимательном изучении мы обнаружим некоторые неясности в этом определении. Иногда ситуация сложнее, чем в программах, встречавшихся нам ранее. Мы не будем сейчас углубляться в этот вопрос и отложим его обсуждение до тех пор, пока не накопим побольше знаний. Программы могут также различаться по сложности. Сложность программы мы будем измерять числом строк в ее тексте. Две строки ПОВТОРИТЬ <число> РАЗ КОНЕЦ будем считать за одну, потому что это две части одной конструкции. Так, например, в программе прибавь 1 ПОВТОРИТЬ 6 РАЗ умножь на 2 прибавь 1 КОНЕЦ четыре строки: прибавь 1 ПОВТОРИТЬ 6 РАЗ КОНЕЦ умножь на 2 прибавь 1 Это означает, что ее сложность равна 4. Заметим, что для всех программ из главы 1 понятия сложности и эффективности попросту совпадают. Например, программа перевозки волка, козы и капусты состоит из 7 строк и требует 7 шагов. То же самое верно и для всех других программ этой главы. У нас просто не было средств для сокращения записи программы. Если нам требовалось исполнить команду, мы должны были вставить ее в текст программы. Посмотрите, например, на программу получения Удвоителем числа 17 (глава 1, раздел 4): 17 шагов выполнения превращаются в 17 строк текста программы. 34 Глава з Теперь же у нас есть средства для сокращения текста программы. Это конструкции процедуры и повторения. Их удобно применять, если в программе одна и та же последовательность команд должна встречаться несколько раз. Так, если Крестьянину нужно перевезти волка, козу и капусту на другой берег только один раз, то нет смысла заводить процедуру перевези вкк — это лишь увеличит сложность программы. А вот для нескольких переправ туда и обратно такая процедура очень полезна. Аналогично если бы мальчикам нужно было перевезти только одного солдата, то конструкция ПОВТОРИТЬ 1 РАЗ оказалась бы излишней, тогда как при замене 1 на 60 использование конструкции повторения приводит к гораздо более простой программе. Заметим, что аналогично тому, как при подсчете сложности программы каждая конструкция повторения считается за одну строку, так же мы поступаем и с конструкцией процедуры: три строки ПРОЦ <имя-процедуры> НАЧАЛО КОНЕЦ считаются одной строкой. 8. Эффективный Удвоитель Построение эффективных программ требует серьезных умственных усилий. Займемся одним частным примером: задачей получения Удвоителем числа 729 из 0 (см. задачу 3.4 в разделе 5). На первом шаге, очевидно, нужно прибавить 1 — умножать на 0 бесполезно. У нас получается 1. На втором шаге можно как умножать на 2, так и прибавлять 1 — результат будет одинаков (т. е. 2). Выберем для определенности умножение. После этого, какое бы число ни было написано на экране, умножение на 2 продвигает нас вперед гораздо быстрее, чем прибавление 1. На первый взгляд умножение на 2 следует использовать, пока это возможно. Избранная стратегия приводит к такой последовательности чисел: о 1 2 4-8 16 - 32 64 128 - 256 — 512. Если мы удвоим еще раз, то получится перелет. Поэтому мы можем только 729 - 512 = 217 раз выполнять команду прибавь 1. Не очень-то эффективная программа, правда? Попробуем прибавить 1 на каком-нибудь промежуточном шаге, выбранном случайно. Конструкция повторения 35 Первая попытка: прибавим 1 к 4 (а после этого будем удваивать). Получаем О — 1 ^ 2 ^ 4 — 5 — 10 -* 20 -» 40 - 80 - 160 - 320 - 640, и теперь мы должны прибавлять 1 всего 729 - 640 = 89 раз. Это уже кое-что! Вторая попытка: прибавим 1 к 2. Получаем о ^ 1 — 2 -> 3 — 6 ^ 12 ^ 24 — 48 — 96 — 192 ^ 384; на этот раз еще хуже, чем в самом первом решении: прибавлять 1 нужно 729 - 384 = 345 раз. Не правда ли, ясно, что прибавлять 1 нужно на каких-то особенных, «наилучших» местах? Но как найти такие места? Следующая идея приходит на помощь во многих играх: начать с конца. Давайте создадим нового Исполнителя, которого назовем Раздвоитель. У него такие команды: вычти 1 раздели на 2 По команде вычти 1 Раздвоитель вычитает единицу из числа на экране. Когда это число равняется нулю, возникает ОТКАЗ. По команде раздели на 2 Раздвоитель делит число на экране пополам. ОТКАЗ возникает, если число нечетное. Получим о из 729. Как умножение на 2 продвигает Удвоителя вперед быстрее, чем прибавление 1, так и деление на 2 продвигает Раздвоителя вперед быстрее, чем вычитание 1. Поэтому нам хотелось бы делить на 2 («раздваивать») всякий раз, когда это возможно. Но теперь само число говорит нам о том, можно ли его делить на 2. А именно если число четное, то мы делим его на 2; если же нет, т. е. число нечетное, то мы можем только вычесть 1 (и в результате получить четное число!). Вот начало программы для Раздвоителя: Команда Число 729 вычти 1 728 раздели на 2 364 раздели на 2 182 Упражнение Закончите программу самостоятельно. 36 г Теперь, когда программа для Раздвоителя закончена, мы можем преобразовать ее в программу для Удвоителя. Для этого будем просто исполнять ее снизу вверх, заменяя всякий раз вычти 1 на прибавь 1, раздели на 2 на умножь на 2. В результате получаем две программы — одну для Раздвоителя, а другую для Удвоителя. Команды для Раздвоителя Число 729 прибавь 1 вычти 1 728 умножь на 2 раздели на 2 364 умножь на 2 раздели на 2 182 умножь на 2 раздели на 2 91 прибавь 1 вычти 1 90 умножь на 2 раздели на 2 45 прибавь 1 вычти 1 44 умножь на 2 раздели на 2 22 умножь на 2 раздели на 2 11 прибавь 1 вычти 1 10 умножь на 2 раздели на 2 5 прибавь 1 вычти 1 4 умножь на 2 раздели на 2 2 умножь на 2 раздели на 2 1 прибавь 1 вычти 1 0 Команды для Удвоителя В нашей программе всего 15 шагов! Задача 3.5 Подсказка Докажите, что любого числа, меньшего 1000, можно достичь из о не более чем за 20 шагов. Если число шагов больше 20, то сколько среди них удвоений? Не меньше... Самые «удобные* числа для Удвоителя — это степени двойки, т. е. числа 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, ... . Мы можем 37 получить их удвоением, без участия прибавления. Самые «неудобные» — это числа, на единицу меньшие степеней двойки, т, е. числа 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, ... . Для того чтобы получить их, нужно вставлять команду прибавь 1 после каждого умножения (проверьте это!). Задача 3.6 Ответ 255. Задача 3.7 Ответ Это Задача 3.8 чить за 14 шагов. Найдите самое первое число, которое нельзя получить за 15 шагов. Постройте самую эффективную программу получения числа 17 из числа 729 для Раздвоителя. ИТОГИ в этой главе вы изучили одну из основных конструкций программирования: конструкцию повторения ПОВТОРИТЬ - РАЗ Эта конструкция позволяет нам писать короткие программы, которые при работе выполняют очень много шагов. Вы также впервые встретились с важными характеристиками качества программы: эффективностью и сложностью. Все это мы будем обсуждать на протяжении всей книги. Вы узнали один из программистских секретов: метод анализа и построения программ с помощью обратных операций. Глава 4 у ^ ‘ -------г— . ■4п'г<1Г\ 1 Условия, или Как использовать обстановку Tij Улучшенный Раздвоитель Напомним, что у Раздвоителя всего две команды: вычти 1 и раздели на 2 При построении эффективной программы для Раздвоителя в предыдущей главе мы проверяли каждое число на экране — четное оно или нечетное. В зависимости от результата использовали подходящую команду — четное число делили на 2, из нечетного вычитали 1. При этом проверку мы выполняли сами, а нам хотелось бы поручить ее программе. Такая возможность существует во всех языках программирования. Введем условие четное Проверить такое условие — то же, что задать вопрос: верно ли, что число на экране четное? Возможных ответов на этот вопрос два: ИСТИНА и ЛОЖЬ. Ответ ИСТИНА означает, что условие выполнено, т. е. число на экране четное. Ответ ЛОЖЬ означает, что число на экране нечетное. Теперь нам нужна возможность использовать результаты проверки. Мы должны сделать что-то одно, если ответ ИСТИНА, и что-то другое, если ответ ЛОЖЬ. Во всех языках программирования для этого служат условные конструкции. И нам они тоже нужны. В этой книге мы будем использовать три формы условных конструкций. Первая (и простейшая) из них имеет вид: ЕСЛИ <условие> ТО <группа команд> КОНЕЦ Условия, или Как использолагь обстановку 39 ЕСЛИ четное ТО раздели на 2 КОНЕЦ Например, можно записать конструкцию (см. справа). Если условие четное истинно, то число на экране разделится на 2. Если оно ложно, то ничего не произойдет. Кстати, заметили ли вы, что мы пишем слова ЕСЛИ, ТО, КОНЕЦ, ИСТИНА, ЛОЖЬ прописными (большими) буквами? Да, вы догадались верно: нам опять встретились универсальные понятия, которые не зависят от Исполнителя. Команды вычитания и деления исполняет Раздвоитель, но конструкция ЕСЛИ — ТО применима к любому Исполнителю и имеет одинаковый смысл для всех них. ИСТИНА и ЛОЖЬ — это универсальные значения истинности условий, общие для всех Исполнителей и не зависящие от их личных условий, а условие четное присуще только Раздвоителю. Не будем откладывать в долгий ящик знакомство со второй формой конструкции ЕСЛИ и приведем ее: ЕСЛИ <условие> ТО <группа команд> ИНАЧЕ <другая группа команд> КОНЕЦ В этом случае мы поручаем Исполнителю выполнить первую группу команд (между ТО и ИНАЧЕ), когда условие истинно, а когда оно ложно, должна быть выполнена вторая группа команд (между словами ИНАЧЕ и КОНЕЦ). Вторая форма конструкции более общая, чем первая. Если мы не хотим ничего делать в случае ложного условия, то группу ИНАЧЕ можно просто оставить пустой. Тогда предыдущий пример можно переписать в виде ЕСЛИ четное ТО раздели на 2 ИНАЧЕ КОНЕЦ Теперь эффективное поведение Раздвоителя описывается просто: ЕСЛИ четное ТО раздели на 2 ИНАЧЕ вычти 1 КОНЕЦ 40 Комментарий Нуль — четное число. Поэтому, когда написанная нами конструкция ЕСЛИ - ТО - ИНАЧЕ встречает нуль, она делит его на 2, и в результате опять получается нуль. Преимущество новой конструкции не только в том, что Раздво-итель выполняет нашу работу. Второе ее достоинство даже важнее: в предыдущей главе мы были а) ПОВТОРИТЬ 20 РАЗ ЕСЛИ четное ТО раздели на 2 ИНАЧЕ вычти 1 КОНЕЦ КОНЕЦ вынуждены писать разные программы для различных чисел. А теперь, сохраняя эффективность, мы получаем универсальную программу. Программа а переводит в нуль любое число, меньшее тысячи. Нам встретился тот редкий случай, когда удалось получить программу, одновременно простую, эффективную и общую, и все это благодаря очень удобной новой конструкции ЕСЛИ — ТО — ИНАЧЕ. На этом мы могли бы остановиться вполне удовлетворенными. Но есть еще две возможности улучшить программу Раздвоителя. Изучим обе. Первая основана на том, что при вычитании 1 из нечетного числа мы непременно получаем число четное. Поэтому нет необходимости проверять непосредствен- б) но после вычитания 1, четное число или нечетное. Оно четное, и мы можем не задумываясь разделить его на 2, делая очередную проверку только после деления. Эти рассуждения приводят к программе б. Преимущество такой группы команд состоит в том, что для любого числа, меньшего 1000, нам достаточно повторить ее 10 раз. ЕСЛИ четное ТО раздели на 2 ИНАЧЕ вычти 1 раздели на 2 КОНЕЦ ПОВТОРИТЬ 10 РАЗ <указанная группа команд> КОНЕЦ Упражнение Запишите программу полностью. Примените ее к числам 100, 299, 35. 41 Если мы будем записывать числа после выполнения всей группы ЕСЛИ — ТО — ИНАЧЕ, то, начав с числа 35, получим последовательность 35^17->8 — 4 — — О — 0^0 — 0. Упражнение Подсказка Почему в последовательности не 10, а 11 чисел? Сколько стрелок между числами? А теперь перейдем ко второй возможности. Очевидным недостатком нашей программы является то, что она не останавливается, дойдя до нуля, а продолжает работать. Она выполняет группу ЕСЛИ - ТО - ИНАЧЕ ровно 10 раз. Чтобы преодолеть это препятствие, необходимо прежде всего ввести новое условие: положительное Заметим, что нуль не является положительным числом. Затем мы должны предложить способ использования ответа на этот вопрос. Введем новый вид конструкции повторения. Новая конструкция поможет повторять группу команд несколько раз, причем число повторений не фиксируется заранее, а будет зависеть от ситуации. Наше предложение по этому поводу простое, но настолько важное, что мы посвятим ему отдельный раздел — раздел 3. 2. Блок-схемы Компьютер понимает тексты, составленные из символов. Человеку же легче глядеть на картинки. Поэтому, когда программист составляет программу для компьютера, он обычно записывает ее на каком-нибудь специальном языке (языке программирования). Но зачастую он представляет программу и в графическом виде — чтобы лучше понять суть дела или объяснить ее своему товарищу. Команда Исполнителя представляется прямоугольником: Внутри прямоугольника обычно записывается текстовое пред- ставление команды, т. е. ее обозначение. Например: перевези волка прибавь 1 вперед 5 42 Г Л А В А 4 Если несколько команд следуют одна за другой, то мы соединяем их стрелками, чтобы знать порядок выполнения команд (см. рисунок справа). Из каждого прямоугольника в программе выходит ровно одна стрелка, а входить в него может несколько стрелок. Условие представляется ромбом: i вычти 1 ~Г~ раздели на 2 раздели на 2 Как правило, внутри ромба записывается текстовое представление условия. Например: В ромб входит несколько стрелок, а выходят из него ровно две стрелки. Если условие внутри ромба истинно, то мы выходим из ромба по стрелке ИСТИНА; в противном случае мы выходим по стрелке ЛОЖЬ. В этом месте программа разветвляется. ЛОЖЬ четное ИСТИНА Теперь мы можем представить конструкцию ЕСЛИ — ТО — ИНАЧЕ с помощью рисунка. Предположим, что у нас есть конструкция ЕСЛИ <условие> ТО <первая группа команд> ИНАЧЕ <вторая группа команд> КОНЕЦ Этой конструкции соответствует рисунок 4.1. Рис. 4.1 Обратите внимание на то, что в каждом прямоугольнике может стоять не одна, а несколько команд (среди которых, возможно, встретятся и конструкции). Описанные схематические изображения программ называются блок-схемами. Такие блок-схемы удобны, если в программе много команд. ЛОЖЬ четное ИСТИНА раздели на 2 ______1 Рис. 4.2 Как мы уже знаем, группа ИНАЧЕ может быть пустой или вообще отсутствовать (рис. 4.2). Например: ЕСЛИ четное ТО раздели на 2 КОНЕЦ или ЕСЛИ четное ТО раздели на 2 ИНАЧЕ КОНЕЦ А вот блок-схема эффективного поведения Раздвоителя, описанного ранее соответствующей программой (рис. 4.3): в этой точке число нечетное в этой точке число четное ЛОЖЬ вычти 1 раздели на 2 I___________: четное ИСТИНА раздели на 2 Рис. 4.3 Через несколько страниц у нас появятся новые примеры блок-схем и их применения. 44 3.! Конструкция повторения I ПОКА - ДЕЛАТЬ Новая конструкция выглядит так: j ПОКА <условие> ДЕЛАТЬ <группа команд> КОНЕЦ Она работает следующим образом. Сначала задается вопрос, стоящий после слова ПОКА. Если ответ ИСТИНА, то выполняется группа команд между словами ДЕЛАТЬ и КОНЕЦ. Затем по окончании процесса исполнения задается тот же самый вопрос. Если ответ ИСТИНА, то все внутренние (стоящие между словами ДЕЛАТЬ и КОНЕЦ) команды опять исполняются. После того как процесс исполнения завершен, вопрос задается в третий раз и т. д. Когда наконец ответом оказывается ЛОЖЬ, конструкция кончает работу. Проиллюстрируем новую конструкцию блок-схемой (рис. 4.4): С помощью этой замечательной конструкции мы можем записать следующую программу для Раздвоителя: ПОКА положительное ДЕЛАТЬ . ЕСЛИ четное ТО раздели на 2 . ИНАЧЕ . вычти 1 раздели на 2 j КОНЕЦ КОНЕЦ . I ! :J и ; . U (С у 45 Соответствующая этой программе блок-схема представлена на рисунке 4.5. Рис. 4.5 Упражнение Примените эту программу к числу 13. Подсчитайте число выполнений команд Исполнителя (попаданий в прямоугольник) и число проверок условий (попаданий в ромб). Можно выписать таблицу состояний, похожую на те, что мы составляли в предыдущей главе. Результат выполнения команды может быть двух типов: во-первых, число на экране, а во-вторых, значение истинности условий. Команда Число Условие четное положительное 13 ЛОЖЬ ИСТИНА вычти 1 12 ИСТИНА ИСТИНА раздели на 2 6 ИСТИНА ИСТИНА раздели на 2 3 ЛОЖЬ ИСТИНА Упражнение Закончите таблицу самостоятельно. Теперь подсчитать число выполнений команд совсем просто. 46 Задача 4.1 Вот еще одна программа для Раздвоителя: ПОКА положительное ДЕЛАТЬ ПОКА четное ДЕЛАТЬ раздели на 2 КОНЕЦ вычти 1 КОНЕЦ а) Нарисуйте блок-схему этой программы. Сравните эту программу с предыдущей программой. б) Примените обе программы к числам 13, 1024, 1023. Сосчитайте число шагов в каждом случае. в) Почему эта программа не может работать бесконечно долго? Задача 4.2 Вот две программы: ПОКА положительное ДЕЛАТЬ вычти 1 ПОКА четное ДЕЛАТЬ раздели на 2 КОНЕЦ КОНЕЦ ПОКА четное ДЕЛАТЬ вычти 1 КОНЕЦ Что плохого в этих программах? Решают ли они задачу обращения в нуль любого числа? 4. Некоторые комментарии к конструкции ПОКА - ДЕЛАТЬ Комментарий 1 Совсем не ставя перед собой такой цели, мы написали программу, применимую к любому натуральному числу, а не только к числам, меньшим 1000. Программа сама выполняет ровно столько шагов, сколько необходимо. Например, для числа 1 000 000 Раздвои-тель выполняет 29 команд. Если число больше, то и выполнение с а : о - к у 47 к программы может потр>ебовать большего числа шагов. Нам не нужно заботиться о числе повторений, как это было в случае конструкции ПОВТОРИТЬ — РАЗ. Программа сама о нем заботится! Комментарий 2 Выполнение конструкции ПОКА — ДЕЛАТЬ начинается с проверки условия. А что, если ответ на самый первый вопрос — ЛОЖЬ? Тогда выполнение прекращается немедленно. Команды, стоящие между ДЕЛАТЬ и КОНЕЦ, не выполняются ни разу. Например, если в приведенной выше программе входное число равно О, то условие положительное ложно и на этом работа кончается — больше ничего делаться не будет. Комментарий 3 А если ответ всегда ИСТИНА и не принимает значения ЛОЖЬ? Тогда программа вообще не прекратит работу. Она будет выполняться бесконечно долго. Так, например, подадим программе ПОКА четное ДЕЛАТЬ раздели на 2 КОНЕЦ число 0. Нуль — число четное, поэтому условие четное истинно, мы делим о на 2 и опять получаем 0. Операции снова выполняются с самого начала, и повторяется это бесконечно. Программисты называют такую ситуацию зацикливанием (или бесконечным зацикливанием). Программисты должны принимать все возможные меры, чтобы избежать зацикливания, но если оно все же произошло, то обычно исполнение программы можно прервать с помощью клавиатуры компьютера. Комментарий 4 Новички иногда думают, что, исполняя внутренние команды, компьютер постоянно имеет в виду условие ПОКА и все время его проверяет. Это не так. Компьютер проверяет условие только после выполнения всех внутренних команд. Проиллюстрируем это на примере. Применим программу 48 к числу 24. ПОКА четное ДЕЛАТЬ раздели на 2 раздели на 2 КОНЕЦ Команда Число Условие Результат четное положительное 24 ИСТИНА ИСТИНА раздели на 2 12 ИСТИНА ИСТИНА раздели на 2 6 ИСТИНА ИСТИНА раздели на 2 3 ЛОЖЬ ИСТИНА раздели на 2 ОТКАЗ ОТКАЗ вызван тем, что перед вторым делением мы не проверяем, является ли число четным. Число 3 нечетное, и это приведет к ОТКАЗу. На блок-схеме ситуация выглядит так: ЛОЖЬ г Рис. 4.6 ИСТИНА раздели на 2 - утгг.: I раздели на 2 I в этой точке условие четное не проверяется Комментарий 5 Возможно, вы заметили, что мы до сих пор не нарисовали блок-схему команды ПОВТОРИТЬ — РАЗ. Причина будет объяснена позднее; мы увидим, что команду повторения ПОВТОРИТЬ — РАЗ легко заменить командой повторения ПОКА — ДЕЛАТЬ. Давайте посмотрим, как можно приближенно оценить число шагов на блок-схеме на рисунке 4.5. Всякий раз, когда мы проходим 49 по ней сверху вниз, Раздвоитель исполняет две или одну команду. За один проход наше число становится по крайней мере в 2 раза меньше (Раздвоитель делит его на 2 на любом пути). Поэтому если мы пройдем по схеме, например, 10 раз, то Исполнитель совершит от 10 до 20 шагов, а число уменьшится по крайней мере в 2^° = 1024 раза. Один миллион приблизительно равен 2^°; на самом деле он немного меньше, чем 2^°. Проверьте это: 220 _ 21° • 21° = 1024 ■ 1024 = ? Значит, нам потребуется не меньше чем 20 ■ 1 = 20 и не больше чем 20 • 2 = 40 шагов, чтобы преобразовать один миллион в нуль. То же самое верно для любого числа, близкого к одному миллиону, скажем, для чисел от 600 000 до 1 040 000. ИТОГИ в этой главе мы узнали, что, помимо команд, у Исполнителей существуют условия. Условия могут быть истинными или ложными. Но важнее всего то, что мы также познакомились с двумя новыми универсальными конструкциями, которые могут реагировать на ответ и изменять поведение Исполнителя в зависимости от ответа. Это: конструкция ветвления ЕСЛИ — ТО — ИНАЧЕ; конструкция повторения ПОКА — ДЕЛАТЬ. Двух новых конструкций для одной главы многовато. Но не отчаивайтесь. Эти конструкции универсальные, т. е. они применимы к любому Исполнителю. Поэтому они будут неоднократно появляться на протяжении всей книги, и у вас будет достаточно возможностей освоиться с ними. Глава 5 Робот ТТ| Где живет Робот Робот живет на плоскости, разделенной на квадраты одинакового размера (рис. 5.1). Он находится на одном из квадратов и может переходить на любой из соседних квадратов, расположенных слева, справа сверху или снизу от того квадрата, на котором находится Робот, но не может переходить на квадраты по диагонали. Кроме того. Робот может закрасить квадрат, на котором находится. Робот выполняет 5 команд: вверх влево вниз вправо закрась Рис. 5.1 Команды вверх, вниз и т. д. заставляют Робота передвинуться на одну клетку в соответствующем направлении. По команде закрась он не двигается, а закрашивает квадрат, на котором находится. Если квадрат уже закрашен, то команда закрась не изменяет цвета квадрата (как будто бы Робот ничего не делает). 2. Стены Интереснее всего в жизни Робота то, что между некоторыми квадратами есть стены (рис. 5.2). Обычно Робот находится в составленном из квадратов прямоугольнике, окруженном стенами со всех четырех сторон. Но и внутри прямоугольника могут быть стены. Иногда они даже образуют сложную фигуру, которую мы будем называть лабиринтом. 51 Рис. 5.2 Робот не способен проходить сквозь стену. Если он попробует сделать это, то разрушится. Или, говоря по-научному, это приведет к ОТКАЗу (см. главу 1, раздел 6). Чтобы предотвратить такой несчастный случай, необходимо проверить четыре условия: сверху свободно слева свободно снизу свободно справа свободно Слово свободно означает, что в указанном направлении нет стены. Робот обнаруживает стену лишь на границе того квадрата, на котором он стоит. «Увидеть» далекую стену он не может, даже если между ним и стеной всего один квадрат. Он способен «дотронуться» только до соседней стены. На рисунке 5.3 можно увидеть значение одного и того же условия сверху свободно в разных ситуациях. Условие сверху свободно (если это ИСТИНА) означает то, что Робот может исполнить команду вверх, не разрушившись. сверху свободно Рис. 5.3 ЛОЖЬ ИСТИНА ЛОЖЬ То же самое верно и для условия слева свободно и команды влево, а также для других подобных пар. Для завершения списка приведем последнее условие: закрашена Это условие позволяет проверить, закрашена или нет клетка, на которой стоит Робот. Оно истинно, если квадрат закрашен, и ложно в противном случае. Как видите, команды Робота очень простые. Но окружающая его среда богата разнообразными возможностями. С помощью различных лабиринтов, коридоров, комнат разной формы и других фигур на поле Робота можно ставить множество интересных задач. 52 ГЛАВА 5 Микромир Робота — отличный полигон для развития алгоритмического мышления. Остальную часть главы мы посвятим различным задачам про Робота и комментариям к ним. Дополнительные задачи для Робота вы найдете в последующих главах. 3. Знакомство с возможностями Робота Задача 5.1 Ответ Напишите процедуру под названием ход конем, которая перемещает Робота из той клетки, где он стоит, в клетку D (рис. 5.4). I ПРОЦ ход конем НАЧАЛО вправо вправо вниз КОНЕЦ i Очевидно, наше решение не единственно, есть и другие решения. Задача 5.2 Напишите все программы, приводящие Робота в точку D за 3 шага. Сколько их получилось? Ответ Таких программ 3. На рисунке 5.5 показаны пути Робота, соответствующие этим программам. Рис. 5.4 t Рис. 5.5 Упражнение Какой рисунок соответствует программе, приведенной в решении задачи 5.1? Ответ Первый. Задача 5.3 Нарисуйте поле Робота ^ ПОВТОРИТЬ 5 РАЗ после исполнения такой . закрась программы (см. справа): | конем Ответ См. рисунок 5.6. _ . Робот 53 Задача 5.4 Команду закрась и процедуру ход конем поменяем местами. Нарисуйте поле Робота после исполнения программы а. Задача 5.5 Заменим число 5 на число 6. Опишите, что произойдет при попытке исполнить программу б. а) ПОВТОРИТЬ 5 РАЗ ход конем закрась КОНЕЦ б) ПОВТОРИТЬ 6 РАЗ ход конем закрась КОНЕЦ Отв^т Процедура ход конем благополучно исполнится 5 раз и нач-“ нет исполняться в шестой раз. Однако Роботу удастся сделать лишь один шаг вправо. При попытке сделать еще один шаг вправо он наткнется на стену, и произойдет авария. Теперь построим на поле Робота стены (рис. 5.7). Рис. 5.6 Задача 5.6 Роботу по-прежнему нужно попасть в точку D. Из трех программ, написанных в задаче 5.2, теперь годится только одна. Найдите ее. Ответ Это программа, соответствующая второму рисунку. Изменим расположение стен на поле (рис. 5.8). Теперь Роботу не удастся попасть в точку D за 3 шага. Задача 5.7 Напишите программу, приводящую Робота в точку D за 5 шагов. Сколько разных программ можно написать? Нарисуйте соответствующие пути Робота. Таких программ всего 4. Ответ Задача 5.8 Для трех различных вариантов начального положения Робота и расположения стен (рис. 5.9) напишите программы, переводящие Робота в точку D. 54 ГЛАВА 5 Рис. 5.8 Рис. 5.9 Задача 5.9 В приведенных ниже программах 5 раз употребляется команда закрась: L: закрась [ закрась вправо 1 вправо закрась : закрась вниз 1 вниз закрась ' закрась вправо ! влево закрась ' закрась вниз * вверх закрась ! закрась Верно ли, что и закрашенных клеток на изображенном на рисунке 5,10 поле будет тоже 5? Ответ Первая программа действительно закрашивает 5 клеток. Вторая программа закрашивает только 4 клетки, так как Робот 2 раза закрашивает одну и ту же клетку. Задача 5.10 Исходное положение Робота показано на рисунке 5.10. Напишите программы, после исполнения которых получатся картинки, изображенные на рисунке 5.11. Рис. 5.10 Рис. 5.11 I 6 а г 55 Задача 5.1 1 Придумайте сами картинку из закрашенных клеток. Пусть это будет задание для вашего товарища, а он пусть придумает задание для вас. А теперь три задачи про озорников. Задача 5.12 ??????? вниз влево влево Решение Задача 5.13 Петя написал на доске программу вверх (см. справа) для Робота. Озорник Ва- вправо ня подбежал и стер одну команду. Какую команду стер Ваня, если известно, что после исполнения Петиной программы Робот возвращается в исходное положение? Это команда вправо. Ясно, что если Робот возвращается в исходное положение, то количество команд вправо и влево должно быть одинаковым. Точно так же одинаковым должно быть количество команд вверх и вниз. Петя написал программу, после исполнения которой Робот возвращается в исходное положение. Ваня стер одну из команд. Однако после исполнения получившейся программы Робот все равно оказывается в исходном положении. Какую команду стер Ваня? Ответ Это команда закрась. Задача 5.14 Решение Петя составил программу, переводящую Робота в клетку D (рис. 5.12). Он написал каждую команду на отдельной карточке и сложил их стопкой в нужном порядке. Но только он собрался переписать программу в тетрадь, как прибежал Ваня и все карточки перемешал. Как ни странно, после этого тоже получилась программа, приводящая Робота в клетку D. Объясните, как это получилось. Программа Пети содержала 7 команд вправо и 4 команды вниз. Любой путь, содержащий 7 шагов вправо и 4 шага вниз, приводит в одну и ту же клетку, а именно — в клетку D. 56 Упражнение Сосчитайте, сколько шагов вправо и вниз сделал Робот на рисунках 5.13—5.15. I I Петина программа Рис. 5.13 Задача 5.15 Решение Робот шел по запутанному лабиринту и нашел клад (закрашенную клетку). Он шел так, как написано в программе (см. справа). Как Роботу выйти из лабиринта, т. е. проделать в точности обратный путь из конечной точки в начальную? Задачу удобно решать, нарисовав путь Робота. Но можно обойтись и без этого. Нам поможет один общий способ рассуждений. Последний шаг, который сделал Робот, был вниз. Значит, его первый шаг в обратный путь будет вверх. Предпоследний шаг Робота был влево; значит, второй шаг на пути обратно должен быть вправо. И так далее. В итоге мы получаем такую программу: вниз вниз вправо вниз вправо вправо вверх влево вверх вправо вверх влево влево вниз вверх вправо вправо вверх вверх 57 D Упражнение Напишите самостоятельно всю программу целиком. Повторим ещ;е раз, в чем состоит метод. Каждое действие нужно заменить обратным: вместо вправо написать влево, вместо влево написать вправо и точно так же заменить вверх на вниз и наоборот. Теперь сами обратные действия надо записать в обратном порядке. Тот же метод можно проиллюстрировать на простом житейском примере. Рассмотрим такое действие: надень носки Обратным ему действием будет сними носки Точно так же действию надень ботинки обратным будет действие сними ботинки Напишем «программу обувания»: I, надень носки надень ботинки Тогда обратная ей «программа разувания» будет выглядеть так: сними ботинки сними носки Мы видим, что в этой программе написаны два обратных действия, и к тому же в обратном порядке! Задача 5.16 Напишите программу перемеш;ений Робота. Пусть ваш товарищ напишет программу, выполняя которую Робот пройдет тот же путь от конца к началу. А вы сделайте то же самое с программой, приготовленной вашим товарищем для вас. Задача 5.17 Известно, что на поле Робота стен нет. Робот исполнил указанную программу. 58 При этом Робот переместился из клетки А в клетку В. Напишите программу, выполняя которую Робот самым коротким путем возвратится из клетки В в клетку А. Постарайтесь обойтись без рисунка. Решение В нашей программе 4 команды вниз и 2 команды вверх. Значит, в результате Робот сместится на 2 клетки вниз. Чтобы вернуться на исходную строку, нужно теперь исполнить 2 команды вверх. Аналогично в нашей программе ’ 3 команды вправо и 2 команды влево. Следовательно, после их исполнения Робот сместится на 1 клетку вправо. Для возвращения в исходный столбец достаточно исполнить 1 команду влево. Итак, простейшая программа, переводящая Робота из В в А, должна содержать 2 команды вверх и 1 команду влево. Поскольку стен на поле Робота нет, эти команды можно исполнять в любом порядке. Например, так (см. справа). вниз вниз вниз вправо вправо вниз вправо вверх вверх влево влево вверх I вверх . влево 4.| Повторяющиеся мотивы Задача 5.18 На поле Робота расположены стены, как показано на рисунке 5.16, а. Нужно перевести Робота в клетку D, а по дороге закрасить клетки между стенами, как показано на рисунке 5.16, б. а) п г б) в) Г “ ■1 “1” 1 1 • Рис. 5.16 Решение Робот несколько раз должен повторять одни и те же действия — например, закрашивать клетку, а потом обходить вокруг стены (рис. 5.16, в). от 59 Давайте оформим эти действия в виде процедуры а. Теперь, казалось бы, нужно повторить процедуру 5 раз, и все. На самом деле если бы мы поступили таким образом, то допустили бы ошибку. Закрашенными оказались бы всего 5 клеток, а последняя, шестая клетка осталась бы незакрашенной. Устранить неприятность можно так: а) ПРОЦ обойди НАЧАЛО закрась вверх вверх вправо вниз вниз КОНЕЦ Задача 5.19 ПОВТОРИТЬ 5 РАЗ обойди < КОНЕЦ I закрась Напишите программу, приводящую Робота в клетку D, т. е. из левого нижнего угла в правый верхний (рис. 5.17). шш Рис. 5.17 Решение Здесь тоже есть часть пути, повторяющаяся в од- ном и том же виде несколько раз. Она показана на рисунке 5.18. Как всегда, удобно оформить этот участок пути в виде про- пРОЦ зигзаг цедуры (см. справа). НАЧАЛО вверх вверх вправо вниз вниз вправо КОНЕЦ 60 Г г. /: Если повторить процедуру 6 раз, то Робот пройдет путь, изображенный на рисунке 5.19. Рис. 5.19 Г1 hi |г- h 1 1 f ■" 1 1 f Т11 f т 1 1 f 711 D 1 ! 11 1 iiiiTii miHiTF 1 1 111 |_ J Lu] L j pljnj и_г| J- Поэтому нужная нам программа выглядит так: ПОВТОРИТЬ 6 РАЗ зигзаг КОНЕЦ вверх вверх Задача 5.20 Проведите Робота в клетку D (рис. 5.20). Рис. 5.20 Подсказка Мы советуем вам найти, как и в предыдущей задаче, повторяющийся участок программы и оформить его в виде процедуры. Та же самая идея используется и в следующей задаче, но лабиринт в ней становится несколько сложнее. Задача 5.21 Проведите Робота в клетку D (рис. 5.21). Рис. 5.21 Мы уверены, что вы сумеете решить задачу самостоятельно. Еще одна ситуация, когда удобно использовать конструкцию ПОВТОРИТЬ — РАЗ: Робот отправляется в дальний путь. В этом случае, вместо того чтобы писать много раз подряд команду вправо, можно употребить конструкцию повторения. о £- о 61 Задача 5.22 Решение Поле Робота представляет собой прямоугольник размером 6 X 12 клеток. Робот стоит в верхнем левом углу (рис. 5.22). Требуется пройти вдоль всей границы поля и закрасить все пограничные клетки. Рис. 5.22 Пойдем сначала вдоль верхней границы. Ее длина составляет 12 клеток, так что мы должны сделать 11 шагов: ПОВТОРИТЬ 11 РАЗ закрась вправо КОНЕЦ , Правая верхняя клетка осталась незакрашенной (рис. 5.23). Мы закрасим ее, проходя вдоль правой границы (рис. 5.24). ПОВТОРИТЬ 5 РАЗ закрась вниз КОНЕЦ Рис. 5.23 Рис. 5.24 62 Упражнение Задача 5.23 Решение Закончите программу самостоятельно. Поле Робота то же, что и в предыдущей задаче, и начальное положение Робота такое же. Требуется закрасить все клетки поля. Ясно, что обойти все поле можно разными способами. Мы предлагаем вам один из них. Сначала напишем процедуру закрась полосу: ПРОЦ закрась полосу НАЧАЛО ПОВТОРИТЬ 11 РАЗ закрась вправо КОНЕЦ закрась КОНЕЦ Обратите внимание на то, что горизонтальная сторона прямоугольника равна 12 клеткам, поэтому Робот должен сдвинуться вправо 11 раз. А закрасить ему нужно все 12 клеток. Вот и приходится вставлять в процедуру еще одну команду закрась, не входящую в цикл. Процедура вернись будет совсем простой: ПРОЦ вернись НАЧАЛО ПОВТОРИТЬ 11 РАЗ влево КОНЕЦ КОНЕЦ Напишем процедуру закрась полосу и вернись: ПРОЦ закрась полосу и вернись НАЧАЛО закрась полосу вернись КОНЕЦ Теперь уже легко написать всю программу целиком: о 6 от 63 закрась полосу и вернись > ПОВТОРИТЬ 5 РАЗ I вниз ‘ I закрась полосу и вернись * КОНЕЦ Упражнение Почему было бы ошибкой написать такую программу: ПОВТОРИТЬ 6 РАЗ закрась полосу и вернись вниз КОНЕЦ Подсказка Мы советуем вам нарисовать картинки, которые помогут ответить на вопрос, что будет на поле после исполнения процедур закрась полосу и закрась полосу и вернись. Вопрос «Что будет на поле?» следует понимать как сразу два вопроса: • Где будет находиться Робот? • Какие клетки будут закрашены? Упражнение Попробуйте написать программу, в которой клетки поля обходятся в другом порядке. В заключение еще две задачи. _____ Задача 5.24 Нарисуйте на клетчатой бумаге путь Робота при исполнении следующей программы (см. справа). Ответ Смотри рисунок 5.25. Такой узор очень любили древние греки. Они часто использовали его при украшении зданий, ваз, одежды и т. д. Греки называли его «меандр» — по названию реки Меандр с очень извилистыми берегами. п L_i г-1 I I J I ------1 г-1 ! I L-I I I --------1 I Г-1 I I L_i I Г-1 ! I 1__| Рис. 5.25 ПОВТОРИТЬ 5 РАЗ вверх вверх вверх вправо вправо вправо вниз вниз влево вверх влево вниз вниз вправо вправо вправо КОНЕЦ 64 ГЛАВА 5 с помощью Робота меандр можно изобразить и иначе — закрашивая клетки (рис, 5.26). Задача 5.25 Рис. 5.26 Напишите программу, изображающую меандр, показанный на рисунке 5.26. 5^ Задачи потруднее в задачах, которые мы решали до сих пор, ситуация на поле была полностью задана. Мы знали где стоит Робот, куда ему нужно прийти, каков размер поля, где на этом поле расположены стены. Т. е, мы знали все то, что можно было знать, и поэтому программы писать было легко: каждый шаг был известен заранее. Лишь программа порой получалась длинной. Гораздо интереснее писать программы, когда что-нибудь заранее неизвестно. Тогда Робот должен сам ориентироваться в обстановке и вести себя по-разному в зависимости от обстоятельств. А нам с вами как программистам следует прюдусмотреть все возможные ситуации. Задача 5.26 Мы не знаем, где стоит Робот. Ему нужно дойти до ближайшей стены, расположенной сверху, и остановиться. Комментарий 1 На рисунке 5.27 изображено несколько разных полей и стрелкой показано, куда Робот должен прийти. - - ж 1 - - - - i 65 в последнем, четвертом случае ему и ходить никуда не надо — он уже стоит у верхней стены. Трудность заключается в том, что мы не можем сказать заранее, сколько шагов вверх придется сделать Роботу: то ли 2, то ли 5, то ли О, то ли 1 000 000 (если поле очень большое). Другими словами. Робот должен «идти вверх, пока это возможно». Комментарий 2 Любую задачу можно представлять себе как игру для двух программистов. Сначала первый пишет программу для Робота — решение поставленной задачи. Потом второй строит поле Робота, удовлетворяющее условию задачи. Он выбирает его размеры, рисует стены и устанавливает Робота, где захочет. После этого Робот выполняет программу первого игрока, и она должна дать правильный результат! Решение Решение нашей задачи на удивление просто. Под- сказка содержится уже в самой формулировке: «идти вверх, пока это возможно». ПОКА сверху свободно ДЕЛАТЬ вверх КОНЕЦ Вот и все! Для большей ясности нарисуем блок-схему этой программы (рис. 5.28). Задача 5.27 Решение Робот находится внутри прямоугольника, других стен на поле нет. Где именно стоит Робот, неизвестно. Напишите программу, приводящую Робота в правый верхний угол. После того как решена предыдущая задача, эта оказывается легкой: 66 ГЛАВА 5 ПОКА сверху свободно ДЕЛАТЬ вверх КОНЕЦ ПОКА справа свободно ДЕЛАТЬ вправо КОНЕЦ Задача 5.28 Предположим, что нас обманули и стены на поле Робота все же есть (рис. 5.29). Чем закончится выполнение предыдущей программы? Ответ Робот попадет в клетку, показанную на рисунке 5.30. — — • Рис. 5.29 Рис. 5.30 Как мы видим, при таком расположении стен задание оказывается невыполненным. Тем не менее у нашей программы есть одно важное достоинство. Если бы мы заранее знали размеры поля и местонахождение Робота, то мы могли бы написать программу попроще: 4 шага вверх и 5 шагов вправо. Тогда, наткнувшись на непредусмотренные стены. Робот потерпел бы крушение. А наша программа к крушению не приводит. Ведь каждый раз перед тем, как сделать шаг. Робот проверяет, нет ли впереди стены. Задача 5.29 Решение Закрасьте все клетки между Роботом и левой стеной и верните Робота в исходное положение (рис. 5.31). Добираться до стены мы уже умеем, так что добавить закрашивание совсем нетрудно: Рис. 5.31 Робот 67 ПОКА слева свободно ДЕЛАТЬ влево закрась КОНЕЦ Теперь надо подумать о том, как вернуться в клетку, в которой Робот стоял сначала. Вспоминаем, что Робот умеет проверять, закрашена ли клетка, и пишем: ПОКА закрашена ДЕЛАТЬ вправо КОНЕЦ Задача решена. Обратим внимание, что именно закрашивание клеток помогло нам вернуть Робота в исходное положение. Без закрашивания Робот не знал бы, где остановиться. Мы-то с вами помним, где Робот стоял, но сам он ничего не помнит; у него нет памяти. Напомним, что Робот — Исполнитель: он умеет исполнять те 5 команд и проверять те 5 условий, которые перечислены в начале этой главы, и больше ничего! Таким образом, мы изобрели полезный прием. В качестве своего рода памяти Робот может использовать закрашенные клетки. Они позволяют проверить, например, был ли Робот когда-нибудь в данной клетке или нет. Почти так же поступал Том Сойер, заблудившись в пещере. Чтобы отличить одно место от другого, он ставил пометки мелом на полу и стенах. Правда, у Тома Сойера было преимущество — он мог ставить разные пометки! Задача 5.30 Решение Поле Робота представляет собой прямоугольник неизвестного размера. Робот стоит в верхнем левом углу. Требуется пройти вдоль всей границы поля и закрасить все пограничные клетки. Может быть, вы обратили внимание, что эта задача почти дословно повторяет задачу 5.22 из предыдущего раздела. Только в той задаче мы знали, в частности, что длина верхней границы составляет 12 клеток, и поэтому делали вдоль нее 11 шагов. Теперь мы этого не знаем и хотим сделать столько шагов вправо, сколько потребуется. Это мы уже умеем. 68 в старой программе: В новой программе: ПОВТОРИТЬ 11 РАЗ закрась вправо КОНЕЦ ПОКА справа свободно ДЕЛАТЬ закрась вправо КОНЕЦ Упражнение 1) Закончите программу самостоятельно. 2) А как поведет себя ваша программа на поле, изображенном на рисунке 5.32, — на прямоугольнике размером 1X1? Да, подобный вариант мы, пожалуй, не предусмотрели. Роботу на таком поле не придется сделать ни одного шага. Но беда не в этом, а в том, что он не закрасит ни одной клетки. А ведь та единственная клетка, которая у нас есть, является пограничной и по условию задачи должна быть закрашена. Проанализируйте вашу программу. Если такое недоразумение возникло, то мы предлагаем добавить в самом конце программы еще одну команду закрась. Упражнение Проверьте, как работает ваша программа на полях, изображенных на рисунке 5.33. Рис. 5.32 В Рис. 5.33 В ™ Задача 5.31 Подсказка Поле Робота — прямоугольник без внутренних стен. Робот стоит в верхнем левом углу. Требуется закрасить все клетки поля. Можно воспользоваться решением задачи 5.23 и переделать его в решение этой задачи. 6.1 Составные условия у вас уже есть известный опыт работы с Роботом. И вы, вероятно, заметили, что мы пока не умеем проверять некоторые очень простые вещи. Так, мы можем проверить, верно ли, что сверху свободно. Или верно ли, что Робот стоит у верхней стены, т. е. сверху не свободно. Нам трудно проверить, верно ли, что Робот стоит в левом верхнем углу, так как это означает сверху не 69 свободно и слева не свободно. При хождении по хитроумным лабиринтам могут потребоваться и другие комбинации условий. Для записи более сложных условий придумано очень удобное средство — логические операции. Таких операций три: И ИЛИ НЕ Условие <условие 1> И <условие 2> истинно тогда и только тогда, когда истинны оба входящих в него условия. Если хотя бы одно из условий ложно, то и все составное условие ложно. Условие <условие 1> ИЛИ <условие 2> истинно, когда одно или оба входящих в него условия истинны. Если же оба условия ложны, то и составное условие ложно. Условие НЕ <условие> истинно, если само условие ложно, и наоборот. Логические операции имеют названия. Операция НЕ называется операцией отрицания. Названия операций И {конъюнкция) и ИЛИ (дизъюнкция) нам в дальнейшем не понадобятся. Логические операции можно применять к любым условиям всех Исполнителей. Поэтому они и записываются большими буквами, подобно конструкциям ПОКА — ДЕЛАТЬ и другим. Логические операции позволяют комбинировать и более сложные условия. Вот, например, как выглядит условие «Робот стоит у нижней стены, но не в углу*: ((НЕ снизу свободно) И слева свободно) И справа свободно Скобки расставляются точно так же, как и в арифметических выражениях: сначала вычисляются значения условий внутри скобок. Упражнение Перед вами три составных условия и три картинки: сверху свободно И слева свободно сверху свободно ИЛИ справа свободно НЕ сверху свободно Рис. 5.34 Определите, истинно или ложно каждое из условий для каждой из картинок на рисунке 5.34. 70 Задача 5.32 Решение Поле Робота — прямоугольник без внутренних стен. Напишите программу, выполняя которую Робот отойдет от стен (если это возможно, т. е. если длина и ширина поля не меньше трех клеток; если поле узкое и отойти от стен невозможно, то пусть Робот делает что угодно, лишь бы не было аварии). Мы приведем здесь не все решение, а только одну четверть. Научим Робота отходить от левой стены: ЕСЛИ (НЕ слева свободно) И справа свободно ТО вправо КОНЕЦ Как видите, мы убедились не только в том, что Робот стоит у левой стены, но и в том, что он может сделать шаг вправо. Упражнение 1) Допишите программу самостоятельно. 2) Проверьте, как будет работать ваша программа на полях, показанных на рисунке 5.35. Рис. 5.35 т ЕО 7. Программы с составными условиями 1. Движемся по коридору. Роботу нужно пройти по коридору из одного угла поля в другой. Точная форма коридора неизвестна. Известно только, что он имеет ширину 1 и тянется в направлении слева-снизу вправо-вверх. Пример такого коридора изображен на рисунке 5.36. Рис. 5.36 Робот 71 Давайте сначала определим, что послужит Роботу сигналом для остановки. Путешествие должно закончиться в верхнем правом углу. Так записывается условие «Робот в верхнем правом углу»: (НЕ сверху свободно) И (НЕ справа свободно) А вот обратное условие «Робот пока еще не в углу»: сверху свободно ИЛИ справа свободно Пока Робот не в углу, он должен двигаться. Значит, наша программа будет выглядеть так: ПОКА сверху свободно ИЛИ справа свободно ДЕЛАТЬ сделай один шаг КОНЕЦ а) Теперь надо решить, в каком направлении сделать шаг. Ответ очевиден. В самом условии цикла ПОКА — ДЕЛАТЬ сказано, что хотя бы одно из направлений — вверх или вправо — обязательно свободно. Шаг можно записать следующим образом (программа а). Вот мы и справились с по- '—- ------- ставленной задачей. 2. Выбираемся из лабиринта. Робот находится где-то в лабиринте. Стены внутри лабиринта имеют вид прямолинейных отрезков и не касаются друг друга и наружных стен (рис. 5.37). Составьте программу, при исполнении которой Робот переместится в верхний правый угол любого такого лабиринта. ПРОЦ сделай один шаг НАЧАЛО ЕСЛИ сверху свободно ТО вверх ИНАЧЕ вправо КОНЕЦ КОНЕЦ Программа, составленная в предыдущей задаче, решает и эту задачу. 72 I Я Упражнение Проследите путь Робота по лабиринту на рисунке 5.37. Упражнение Составьте программы, приводящие Робота: • в верхний левый угол; • в нижний левый угол; • в нижний правый угол. 3. Ищем клад. Поле Робота — прямоугольник без внутренних стен. Робот стоит в левом нижнем углу. Где-то на поле имеется клад (закрашенная клетка) (рис. 5.38). Найдем его. Рис. 5.38 Робот должен остановиться, попав на закрашенную клетку, а до тех пор двигаться. По-видимому, разумно начать программу таким образом: ПОКА НЕ закрашена ДЕЛАТЬ КОНЕЦ Теперь давайте обдумаем, как он будет двигаться. Нам кажется, что легче всего искать клад, двигаясь всегда в одном направлении, снизу вверх. Уточним: это легче для нас как составителей программы, а Роботу-то как раз работы прибавится! Но просто сделать шаг вверх нельзя, есть опасность разбиться о стену. Поступаем так: ЕСЛИ сверху свободно ТО вверх ИНАЧЕ КОНЕЦ Что означает случай ИНАЧЕ? Он означает, что Робот уперся в верхнюю стену. Следовательно, на этой вертикали мы клада не оьот 73 нашли. Теперь нужно вернуться назад и перейти на соседнюю вертикаль. Это программируется легко: ' ПОКА снизу свободно ДЕЛАТЬ ^ вниз ' КОНЕЦ , ЕСЛИ справа свободно ТО | вправо i i КОНЕЦ i Соберите все части этой программы вместе — и задача решена. Упражнение Как поведет себя Робот, если клада на поле нет? Приведем две задачи для самостоятельного решения. Задача 5.33 Робот стоит снизу от горизонтальной стены, у ее левого края. Длина стены неизвестна. Требуется закрасить все клетки под стеной (рис. 5.39). Рис. 5.39 Задача 5.34 Рис. 5.40 Внутренние стены на поле Робота образуют прямоугольник неизвестных размеров. Робот стоит снизу от левого нижнего угла прямоугольника. Требуется закрасить все клетки вокруг прямоугольника (рис. 5.40). 74 Г Л А В А 5 Ю пример сложной программы Наверное, вам будет интересно увидеть хотя бы один пример сложной программы. Конечно, наша программа не сравнится по сложности с теми, что пишутся профессиональными программистами. Их программы достигают размера в тысячи строк, а коллективы программистов составляют программы и в миллионы строк. Наша программа легко уместится на одной странице. Но все же она является достаточно сложной. И вот в каком смысле: даже опытному программисту надо хорошенько подумать, чтобы решить предлагаемую ниже задачу. Задача 5.35 Робот находится где-то в лабиринте, изображенном на рисунке 5.41. Стены внутри лабиринта имеют вид прямолинейных отрезков. Они не соприкасаются друг с другом, но могут прикасаться к наружным стенам. Требуется написать программу, при исполнении которой Робот попадет в верхний правый угол. 1 D — 2 3 - • - Рис. 5.41 углы запрещены Комментарий Попытка воспользоваться программой перемеш;ения Робота по лабиринту из предыдущего раздела к успеху не приводит. Исполнив эту программу. Робот придет в клетку 1 и решит, что он уже достиг нужного угла. Можно попытаться продолжить программу дальше, приказав Роботу обходить вертикальные перегородки. Но тут нас поджидает другая трудность. Неясно, когда Робот должен остановиться. В самом деле. Робот 75 придя в клетку D, Робот отправится в сторону клетки 2 обходить очередную перегородку. Это ему не удастся. Но то, что легко выражается на человеческом языке («не удалось обойти очередную стену»), довольно трудно сформулировать на языке Робота. Решение Давайте решать задачу с самого начала. План ' действий таков: • продвигаться к верхней границе; • затем, достигнув ее, двигаться к правой границе. Сразу поставим себе условие: продвигаясь вверх. Робот не сделает ни одного шага вниз. Ни шагу назад! Начнем с поиска прохода вверх. Некоторая трудность состоит в том, что непонятно, с какой стороны его искать. Например, на нашем рисунке проход находится справа от Робота. Но если бы Робот стоял в клетке 3, то проход был бы слева. Мы поступим вот как: сначала уведем Робота до упора влево, а уже потом будем двигать его вправо в поисках прохода. Итак, ПРОЦ ищи проход вверх НАЧАЛО ПОКА слева свободно ДЕЛАТЬ влево КОНЕЦ .... (иди вправо и ищи проход вверх) КОНЕЦ Теперь закончить процедуру несложно. ПОКА справа свободно И (НЕ сверху свободно) вправо КОНЕЦ Обратите внимание, что на протяжении всей процедуры Робот продвигался только по горизонтали — либо влево, либо вправо. Процедура заканчивается одним из двух: • либо Робот прошел до упора вправо, но прохода так и не обнаружил; это означает, что он уже находится у верхней границы; • либо обнаружен проход вверх; тогда можно сделать шаг вверх и начать все сначала, т. е. снова искать проход вверх. 76 Мы приходим к такой программе: ПРОЦ иди к верхней границе НАЧАЛО ищи проход вверх ПОКА сверху свободно ДЕЛАТЬ вверх ищи проход вверх КОНЕЦ КОНЕЦ Упражнение Упражнение Подсказка Теперь Робот достиг верхней границы. Что делать дгшьше? Продолжать в том же духе! Тем же методом двигаемся вправо: сначала ищем проход вправо, потом делаем niar вправо и снова ищем проход вправо и т. д. Для этого надо в уже написанных процедурах заменить вверх на вправо и внести еще кое-какие изменения. Допишите программу до конца самостоятельно. Нарисуйте блок-схему программы. Искать проход вправо можно одним из двух способов: • сначала уходить вниз, а потом искать проход, продвигаясь вверх; сначала уходить вверх, а потом искать проход, продвигаясь вниз. Как вы считаете, можно ли выбрать любой из этих способов или годится только один из них? Один из способов ошибочен: он приведет нас в клетку 2. Будьте внимательны! ИТОГИ в этой главе мы познакомились с Исполнителем Робот и написали для него несколько программ. Хотя Робот и простой Исполнитель, задачи для него могут быть очень сложными. Использование условий позволяет писать программы, подходящие одновременно для разных полей. При этом очень удобно пользоваться составными условиями, которые строятся из простых с помощью трех логических операций. Глава 6 ^ Чертежник Tij Точки и векторы но плоскости Упражнения Числа помогают работать с плоскостью. Нарисуем на плоскости две перпендикулярные прямые. Это оси координат. Горизонтальная называется осью х, а вертикальная — осью у. Поставим на осях числа, как показано на рисунке 6.1. Тогда каждую точку плоскости можно обозначить парой чисел: первое число взято из оси X, а второе — из оси у. Эти числа являются координатами точки. Координаты — вещественные (необязательно целые) числа. 1) Запишите координаты точек А, В, С, D, Е, F, G, Н на рисунке 6.2. 2) Нарисуйте точки с координатами (О, 0) (2.5, -5) (4, 0) (1, 0) (3.14, 2.72) (0, -2) (0, 1) (1.3, 1.3) (0, 3) и т. д.; можете придумать собственные точки. V, 1 1 1 ‘ (5.3) Vi 1 [B t 1 1 , 1 1 1 H •A -5 -4 -3 -2 -i -1 -2 -3 -4 -5 0 i 2 3 4 C 1 ^ 1 G 0 1 1 F 1 D -----М2, -4,5) E Рис. 6.1 78: ГЛАВА с Рис. 6.2 Обратите внимание: вместо запятой при записи десятичных чисел в алгоритмике используется десятичная точка. Это объясняется тем, что запятая несет другие нагрузки, а также традицией. В англоязычных странах точка всегда играла эту роль, и именно в них родились наиболее распространенные языки программирования. 2. Команды Чертежника Чертежник — устройство для изображения рисунков и графиков, состоящих только из отрезков прямых линий. Он рисует на плоскости с координатами. Можете представлять себе плоскость как лист бумаги или экран компьютера. У Чертежника есть перо, которое бывает поднятым или опущенным. Перо можно двигать по плоскости. Поднятое перо не оставляет на плоскости следа. Если мы опустим перо, а затем на том же самом месте его поднимем, то оно отметит точку на плоскости. В начальном положении перо поднято и находится в точке (О, 0). У Чертежника всего 4 команды: подними перо опусти перо переведи в точку (<число>, <число>) сдвинь на вектор (<число>, <число>) Смысл первых двух команд понятен. Две другие команды требуют дополнительных комментариев. Для перехода в точку (3, 2) можно пользоваться командой переведи в точку (3, 2) Где бы ни было перо перед выполнением этой команды, после ее выполнения оно окажется в точке (3, 2), что проиллюстрировано на рисунке 6.3. Перейдем к команде сдвинь на вектор. Вектор — это направленный отрезок. Он задается своими координатами. Нарисуем, скажем, вектор (3, 2), выходящий из точки (0, 0) (рис. 6.4). Чертежник 79 -5 -Л -3 -2 -1 yk 5 4' 3 2------ 1 (3,2) О 1 2 3 4 5 X Рис. 6.4 Его начало — точка (О, 0), а конец — точка (3, 2). Вектор (3, 2), выходящий из любой другой точки, будет таким же по величине и направлению (рис. 6.5). После выполнения команды сдвинь на вектор положение пера зависит от того, где оно находилось. В этом ее отличие от команды переведи в точку, после которой перо оказывается в указанной точке независимо от своего предыдущего положения. Составим для примера программу, рисующую букву *М», как показано на рисунке 6.6. Мы хотим, чтобы после исполнения программы перо находилось в точке В и было поднято. Рис. 6.5 Рис. 6.6 Каждое движение пера можно задать двумя способами: командой переведи и командой сдвинь. Мы напишем две процедуры. В одной будут только команды переведи, в другой — только команды сдвинь (хотя, конечно, оба вида команд можно смешивать в одной программе): 80 I ПРОЦ М-переведи НАЧАЛО опусти перо переведи в точку (О, 4) переведи в точку (1, 2) переведи в точку (2, 4) переведи в точку (2, О) подними перо переведи в точку (3, О) КОНЕЦ ПРОЦ М-сдвинь НАЧАЛО опусти перо сдвинь на вектор (О, 4) сдвинь на вектор (1, -2) сдвинь на вектор (1,2) сдвинь на вектор (О, -4) подними перо сдвинь на вектор (1,0) КОНЕЦ Чтобы лучше во всем разобраться, посмотрим на каждое движение по отдельности (рис. 6.7). Vi ■ 4* 1 . . . ■ 4 ^ . • 3-t • • • • 3 .',. . . • 2- • 2 • 1- • 1 , . . . -1 •-1 0 1 2 3 *х -i •-1 0 1 2 3 *х переведи в (0, 4) переведи в (1,2) ИЛИ ИЛИ сдвинь на (0,4) Рис. 6.7 сдвинь на(1, -2) ч 4 3 2 1 -1 •-1 0 12 3 переведи в (2, 4) или сдвинь на (1,2) У, ■ 4 • 3 • 2 • 1 -1 •-1 -L 0 1 2 3 X переведи в (2, 0) или сдвинь на (0, -4) Обе процедуры приводят к одному и тому же результату, но у второй есть одно преимущество. Чтобы обнаружить его, изменим начальную точку. Пусть перо стоит, скажем, в точке (3, 3); выпол- Так случилось потому, что из одной и той же точки (3, 3) команда переведи в точку (О, 4) переводит перо в точку (О, 4), а команда сдвинь на вектор (О, 4) — в точку (3, 7). Упражнение Добавив в процедуру М-переведи две команды, добейтесь того, чтобы она правильно рисовала букву «М* из начала координат независимо от исходного положения пера. 3^ Арифметические выражения Чертежнику все время приходится работать с числами. А где числа, там и вычисления. Поэтому давайте введем такое правило: СИНТАКСИЧЕСКОЕ ПРАВИЛО • Везде, где стоит число, можно поставить равное ему арифметическое выражение. Так, вместо команды переведи в точку (6, 4) можно написать любую из следующих команд: переведи в точку (З-нЗ, 2+2) переведи в точку (1-t-2-(-3, 5-1) переведи в точку (6, 6-2) Запись арифметических выражений в алгоритмике имеет свои традиции. Сложение и вычитание обозначаются обычными знаками * + * и ♦-♦. Умножение в алгоритмике обозначается не точкой и не косым крестиком, как в арифметике, а знаком ♦** (звездочка). Деление в алгоритмике всегда обозначается косой чертой «/». в математике дроби часто записывают в «два этажа»: ------- 2 В алгоритмике принято все писать в одну строку. Поэтому предыдущую дробь запишем так: (3-1-5)/2. То же самое относится и к возведению в квадрат. Мы не можем написать «двухэтажное выражение» 5^, а должны писать 5*5. 82^ ГЛАВА 6 СИНТАКСИЧЕСКОЕ ПРАВИЛО • Арифметические выражения пишутся в одну строчку. Еще примеры записи команды переведи в точку (6, 4): переведи в точку (2*3, 8/2) переведи в точку (2*(2+1), (3+5)/2) Задача 6.1 Решение переведи в точку (2*4-2, 4) В предыдущем разделе приведена программа рисования буквы Напишите программу, рису- ющую букву «М» вдвое большего размера. Новую программу можно получить с помощью простого преобразования старой: опусти перо сдвинь на вектор (О, 4) сдвинь на вектор (1, -2) сдвинь на вектор (1,2) сдвинь на вектор (1, -4) опусти перо сдвинь на вектор (0*2, 4*2) сдвинь на вектор (1*2, -2*2) сдвинь на вектор (1*2, 2*2) сдвинь на вектор (0*2, -4*2) Разумеется, все арифметические выражения можно было бы заранее вычислить и записать готовые числа: опусти перо сдвинь на вектор (0, 8) сдвинь на вектор (2, -4) сдвинь на вектор (2, 4) сдвинь на вектор (0, -8) Результат исполнения будет тот же самый. Задача 6.2 а) Напишите программу, рисующую букву «М* вдвое меньшего размера. б) Напишите программу, вытягивающую букву ♦ М» вдвое по вертикали. Подсказка Вы можете поделить каждое число на 2, а можете умножить на 0.5. 4tipT0:::HMK 83 4. Разные задачи для Чертежника Поупражняемся с командами Чертежника. Задача 6.3 В каждой строке приведенной ниже таблицы указана точка, в которой стоит перо, и команда Чертежника. Укажите точку, в которую придет перо. Нарисуйте на клетчатой бумаге получившийся отрезок (перо опущено). Начальная точка Команда Чертежника Конечная точка (0. 1) переведи в точку (3, 2) (0, 1) сдвинь на вектор (2, 3) (1. -2) переведи в точку (-3, 1) (-1. -1) сдвинь на вектор (2, 2) (3. 3) переведи в точку (2, 4) (3. 3) сдвинь на вектор (-6, 0) (-2. -1) переведи в точку (0, 0) (-2. 1) сдвинь на вектор (0, 0) (-2. 1) переведи в точку (-2, 1) Задача 6.4 Напишите программы рисования простых картинок, как на рисунке 6.9: Давайте составим программу рисования улицы из четырех домиков (рис. 6.10). 84 Рис. 6.10 На первый взгляд задача представляется чересчур сложной. Но если умело разбить ее на процедуры, то она окажется легкой. Начнем с того, что нарисуем квадрат: i ПРОЦ квадрат ; НАЧАЛО опусти перо > сдвинь на вектор (4, О) I сдвинь на вектор (О, 4) * сдвинь на вектор (-4, 0) сдвинь на вектор (0, -4) КОНЕЦ Затем нарисуем крышу: ПРОЦ крыша НАЧАЛО сдвинь на вектор (2, 2) сдвинь на вектор (2, -2) КОНЕЦ Теперь легко нарисовать домик: ПРОЦ домик НАЧАЛО квадрат , сдвинь на вектор (0, 4) крыша ^ КОНЕЦ Пока получился домик без окошка (рис. 6.11). Точкой мы отметили то место, где остгилось перо. Следующий шаг — рисование окошка: I е р . е ж н и к 85 ПРОЦ окошко НАЧАЛО сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на КОНЕЦ вектор вектор вектор вектор вектор вектор вектор вектор (2, О) (О, 2) (-2, 0) (0, -2) (0, 1) (2. 0) (-1, 0) (0, -1) Окошко готово, так что можно рисовать домик с окошком. Попробуем: ПРОЦ домик с окошком НАЧАЛО домик окошко КОНЕЦ Вот что у нас получилось в результате: Рис. 6.12 Беда в том, что Чертежник начал рисовать окошко с той точки, где перед этим находилось перо (рис. 6.12). Мы забыли поместить его в нужную точку. Давайте сделаем это и обязательно поднимем перо, чтобы не оставлять лишних линий! Итак, вторая попытка (см. справа). Вот теперь домик получился что надо! ПРОЦ домик с окошком НАЧАЛО домик подними перо сдвинь на вектор (-3, -3) опусти перо окошко КОНЕЦ 86 ГЛАВА 6 Точкой мы снова отметили то место, где находится перо (рис. 6.13). Сейчас уже ничего не стоит нарисовать улицу: ПРОЦ улица НАЧАЛО I' ПОВТОРИТЬ 4 РАЗ домик с окошком подними перо сдвинь на вектор (4, -1) КОНЕЦ подними перо переведи в точку (О, 0) КОНЕЦ Вот мы и справились с этой задачей! Обратите внимание: в самом конце мы подняли перо и отвели его в исходное положение. Это своего рода проявление программистской аккуратности — не бросать перо где попало. Полезно еще раз с высоты птичьего полета посмотреть на то, как устроены наши процедуры. Процедура улица использует в качестве своего помощника служебную процедуру домик с окошком. Процедура домик с окошком сама имеет двух помощников: процедуры домик и окошко. Наконец, в свою очередь, процедура домик пользуется двумя процедурами квадрат и крыша. Схема подчинения процедур друг другу показана на рисунке 6.14. Рис. 6.14 Р е н “ 87 Задача 6.5 Напишите процедуры рисования букв «К*, *0*, «Т» в том виде, как они показаны на рисунке 6.15. Назовите эти процедуры буква К, буква О, буква Т. Рис. 6.15 Комментарий Следуя принципу «не бросать перо где попало», давайте с самого начала условимся: каждая процедура начинается в точке А (перо поднято) и оканчивается в точке В (перо тоже поднято). Советуем вам пользоваться только командой сдвинь на вектор. Задача 6.6 Составьте программу, которая пишет слово «КОТ». Решение Задача 6.7 А В Рис. 6.16 Задача 6.8 Решение Если вы выполнили все условия пре- буква К дыдущей задачи, то нужная нам про- буква О грамма (см. справа) легко составляет- буква Т ся из трех процедур. Нарисуйте на клетчатой бумаге буквы «Е» и «А» высотой в 4 клеточки и шириной в 2 клеточки. Напишите процедуры рисования этих букв Чертежником. Следите за тем, чтобы соблюдалась наша договоренность: в начале каждой процедуры перо находится в точке А (левом нижнем углу того прямоугольника, в котором пишется буква), а в конце оказывается в точке В (на три клетки вправо от точки А) (рис. 6.16). Составьте программу, с помощью которой Чертежник напишет фразу «КОТ КАТАЕТ». Вам понадобится пробел между словами. Удобно заранее заготовить совсем простую процедуру: ПРОЦ пробел НАЧАЛО сдвинь на вектор (3, 0) КОНЕЦ 88 Наша программа будет выглядеть следующим образом (см. справа). Обратите внимание на то, что некоторые процедуры используются по нескольку раз. Задача 6.9 Напишите программы для записи следующих слов и выражений: а) ТОК г) ТЕК ТОК б) ТАКТ д) КАТОК в) КАТЕТ е) А КТО КАТАЕТ КОТА Вы уже вполне готовы к выполнению небольшого коллективного проекта. буква К буква О буква Т пробел буква К буква буква буква буква буква Задача 6.10 Задача 6.11 Распределите все буквы русского алфавита между учениками вашего класса. Напишите процедуры рисования всех букв. Теперь вам будет легко писать программы для Чертежника, печатающие любой русский текст. Позаботьтесь о том, чтобы длинный текст можно было печатать на нескольких строчках. Напишите программы рисования картинок, изображенных на рисунке 6.17, одним росчерком пера, т. е. таким образом, чтобы в процессе исполнения программы перо ни разу не поднималось вверх и ни одна линия не проводилась дважды. Подсказка Если на рисунке есть точки, в которых сходится нечетное число линий (3, 5 или 7), то начинать надо в одной из таких точек. На последнем рисунке они выделены (рис. 6.17). Советуем вам сначала поупражняться на бумаге, а уже потом писать программу для Чертежника. 89 А теперь займемся исследованием программ. Задача 6.12 Перед вами две программы. До начала их исполнения перо поднято и находится в начале координат. переведи в точку (2, 1) опусти перо сдвинь на вектор (О, 3) ПОВТОРИТЬ 3 РАЗ сдвинь на вектор (1,0) сдвинь на вектор (0, -1) КОНЕЦ переведи в точку (2, 1) подними перо опусти перо сдвинь на вектор (1,3) сдвинь на вектор (Л, 2) сдвинь на вектор Hi 1) сдвинь на вектор (1i 0) сдвинь на вектор (1, -1) сдвинь на вектор (1, -2) сдвинь на вектор (1, -3) подними перо Не исполняя этих программ и не рисуя получившихся фигур, ответьте на следуюш;ие вопросы: а) После исполнения программ перо будет поднято или опуш;ено? б) Где будет расположено перо после исполнения каждой программы? Какова координата х конечного положения, какова координата i/? в) Будет ли нарисованная ломаная замкнутой? г) Что будет, если поменять знаки у всех чисел на противоположные? д) Что будет, если поменять знак только у первого числа каждой пары? только у второго числа? Ответив на эти вопросы, нарисуйте две фигуры и проверьте свои ответы. Ответы а) Обе программы заканчиваются командой подними перо, так что перо после их исполнения будет поднято, б) В первой программе последняя команда перемещения — это переведи в точку (2, 1). Поэтому независимо от всего предыдущего перо окажется в точке (2, 1). Во второй программе координаты конечной точки придется вычислять. При последовательном исполнении команд сдвинь на вектор координаты х и у складываются. Следовательно, = 1 = 3 1 + о - 1 + 1 - 1 -Ь 1 = 2 - 3 = 7, 0. Итак, конечное положение пера — точка (7, 0). 90 в) Первая программа рисует замкнутую ломаную, вторая нет. г) Получится фигура, симметричная исходной относительно начала координат. д) Если поменять знаки у координат х, то полученная фигура будет симметрична исходной относительно оси у, а если поменять знаки у координат у — относительно оси х. Давайте поучимся рисовать параболу. Парабола — кривая, точки которой удовлетворяют уравнению у = х^. Эту кривую вы будете изучать в 8 классе. Программа, которую мы напишем, будет рисовать не всю часть параболы, изображенную на рисунке 6.18, а только тот ее кусок, который лежит между точками (О, 0) и (1, 1). Чертежник умеет чертить только прямолинейные отрезки. Возникает естественный вопрос. Как же он сможет нарисовать кривую? Разгадка проста. Мы будем рисовать параболу приближенно. Давайте разобьем наш участок параболы на 10 частей, поставив на ней точки, отвечаюш;ие значениям д: = 0, 0.1, 0.2, ... , 0.9, 1. А потом соединим эти точки ломаной. Упражнение Чему равны значения у в указанных точках? Ответ у = 0^, 0.1^, 0.2^, ... . Чтобы не заниматься вычислениями, мы можем прямо писать в командах выражения 0.1*0.!, 0.2*0.2 и т. д. Получается следуюш;ая программа: I опусти перо I переведи в точку (0.1, 0.1 *0.1) переведи в точку (0.2, 0.2*0.2) переведи в точку (0.3, 0.3*0.3) переведи в точку (0.9, 0.9*0.9) переведи в точку (1, 1*1) Если бы у нас хватило терпения написать программу не из 10 команд перемещения, а, например, из 100, то полученную ломаную на глаз было бы невозможно отличить от кривой. Когда вы р т е ж н и 91 познакомитесь с переменными, вы научитесь записывать все перемещения пера в этой задаче в 3 строчки независимо от того, сколько их — 10 или 100. Упражнение Напишите программу рисования отрезка параболы от точки (0, 0) до точки (2, 4). Количество частей, на которые вы хотите разбить этот отрезок, выберите сами. При рисовании ломаной мы до сих пор использовали команду переведи в точку. Параболу можно нарисовать и при помощи команды сдвинь на вектор, хотя это требует некоторой сообразительности: опусти перо сдвинь на вектор (0.1, 0.01) сдвинь на вектор (0.1, 0.03) сдвинь на вектор (0.1, 0.05) сдвинь на вектор (0.1, 0.07) Упражнение Угадайте закономерность, проверьте ее на дальнейших точках и допишите программу до точки (1, 1). ИТОГИ Исполнитель Чертежник, с которым мы познакомились в ц этой главе, — ваш первый графический Исполнитель. Он может рисовать простые картинки и графики функций. На j самом деле он способен изобразить на плоскости все, что угодно, но программа может оказаться очень длинной. При рисовании Чертежник использует координаты на ^ плоскости. Координаты представляются числами и ариф- ; метическими выражениями. У Чертежника два типа команд движения: переведи в точку и сдвинь на вектор. Команды первого типа удобны, когда требуется нарисо- ; вать картинку в определенном месте плоскости, а команды второго типа — если картинку нужно перемещать в произвольное место. Глава 7 Черепаха □ОоОаооСаОп 1, Где живет Черепаха и что она может делать Черепаха еще один Исполнитель, способный передвигаться по плоскости. Только плоскость не разделена на квадраты и не имеет координат; это просто чистая и пустая плоскость. Можете считать ее большой песчаной пустыней. Если Черепаха движется по пустыне с опущенным хвостом, то от нее остается след; если с поднятым, то следа нет. Хвостом управляют две команды: подними хвост и опусти хвост у Черепахи есть голова. Черепаха может двигаться только по прямой и только вперед (в том направлении, куда она смотрит) или назад: вперед (<расстояние>) назад (<расстояние>) Вместо слова <расстояние> мы должны поставить число или арифметическое выражение. Расстояние измеряется в шагах. В каждом из приведенных ниже примеров Черепаха делает 20 шагов вперед: вперед (20) вперед (5*4) вперед (5-1-15) вперед ((3-1-39)/2-1) В начале выполнения каждой программы Черепаха смотрит вверх. Чтобы изменить направление движения Черепахи, мы f>aenaxa 93 должны приказать ей повернуться. Заставляют Черепаху повернуться две команды: вправо (<угол>) и влево (<угол>) Углы измеряются в градусах. Команда вправо (90) означает «повернись на 90 градусов вправоВместо слова <угол> вы можете записывать любое число или арифметическое выражение. Чтобы лучше представить себе, как Черепаха исполняет команду поворота, попробуйте поставить себя на ее место. Итак, всего мы выписали 6 команд Черепахи, и это все. Надеемся, вы будете восхищены тем, сколько различных вещей можно сделать, пользуясь таким небольшим набором команд. 2. Повороты Полный оборот составляет 360° — вот главное, что нужно знать про повороты. Если Черепаха повернется на 360°, то ее нос будет смотреть точно в ту же сторону, что и до поворота. Впрочем, то же самое произойдет не только с Черепахой, но и с человеком, с лодкой, с автомобилем. Повороты направо и налево могут за-I менять друг друга. Вместо вправо (90) вправо(90) Рис. 7.1 влево(270) напишем влево (270) Результат получим тот же самый (рис. 7.1). Аналогично вместо влево (45) можно написать вправо (315) Как мы узнали правильные числа? Вот как: 270° = 360° - 90°, 315° = 360° - 45°. 94 Упражнение Определите направление Черепахи после исполнения каждой из следующих программ: влево (75) 1) вправо (180) ; 4) 2) влево (360) 5) 3) вправо (100) 5) ; ПОВТОРИТЬ 17 РАЗ вправо (360/17) КОНЕЦ 3. Рисуем квадрат Задача 7.1 Решение Напишите программу рисования квадрата со стороной 40. Для начала можно попробовать рисовать квадрат шаг за шагом (программа а). Вскоре мы, однако, обнаруживаем, что повторяем одни и те же команды. Поэтому мы можем написать такую процедуру (см. программу б): а) опусти хвост вперед (40) вправо (90) вперед (40) вправо (90) б) I ПРОЦ квадрат Г НАЧАЛО , опусти хвост ; ПОВТОРИТЬ 4 РАЗ ^ вперед (40) I вправо (90) КОНЕЦ КОНЕЦ Каждое из четырех исполнений команды вперед — проход по одной из сторон квадрата. Каждое из четырех исполнений команды вправо — поворот в одном из углов квадрата. Четыре поворота на 90° в сумме дают поворот на 360°. Следовательно, после исполнения процедуры Черепаха стоит в том же самом месте и смотрит в ту же сторону, что и вначале. 4. Что легко для Черепахи и трудно для Чертежника и наоборот Нарисовать квадрат с диагональю с помощью Чертежника очень просто. Такие задачи мы решали в предыдущей главе. А вот для Черепахи это задача трудная. Сначала нужно повернуть Черепаху черепаха 95 Легко Чертежнику, Рис. 7.2 трудно Черепахе Легко Черепахе, трудно Чертежнику на 45°, чтобы она встала вдоль диагонали, что легко. Но нарисовать диагональ мы сумеем, только если будем знать ее длину. Тот, кому знакома теорема Пифагора, может воспользоваться ею и вычислить длину диагонали квадрата. А теперь давайте посмотрим на квадрат, повернутый на 45° (рис. 7.2). Если бы мы захотели нарисовать его с помощью Чертежника, то нам пришлось бы выяснять координаты всех вершин квадрата, что не так уж просто. А вот Черепахе справиться с такой задачей вправо (45) ничего не стоит. Смотрите, как она это делает квадрат (см. справа). Задача 7.2 Черепаха исполнила такую программу: ПОВТОРИТЬ 8 РАЗ квадрат вправо (45) КОНЕЦ Что она нарисовала? От^ет Она нарисовала 8 квадратов, при этом каждый следую-“ щий будет повернут относительно предыдущего на 45° (рис. 7.3). Задача 7.3 Черепаха исполнила такую программу: ПОВТОРИТЬ 12 РАЗ квадрат вправо (30) КОНЕЦ Что она нарисовала? 96 ГЛАВА Комментарий Обратите внимание на соотношение между числом квадратов и углом поворота: 8 • 45° = 360°, 12 • 30° = 360°. 5. Что можно сделать из квадратов Мы уже видели на двух предыдущих примерах, что из такой простой фигуры, как квадрат, можно строить довольно красивые узоры. Сейчас мы приведем еще несколько примеров. Задача 7.4 Решение Напишите программу рисования клетчатой доски (рис. 7.4). Рис. 7.4 Начнем с того, что напишем процедуру маленький квадрат. Она должна отличаться от процедуры квадрат только тем, что маленький квадрат будет иметь сторону 5 вместо 40. Черепаха заканчивает рисовать квадрат в исходном положении. Затем из восьми маленьких квадратов нарисуем вертикальную полосу: ПРОЦ вертикальная полоса | НАЧАЛО ПОВТОРИТЬ 8 РАЗ маленький квадрат вперед (5) КОНЕЦ назад (40) КОНЕЦ Мы закончили процедуру командой назад (40), чтобы Черепаха, нарисовав полосу, вернулась в Ч . ■ ( 97 исходное положение. Далее из 8 полосок можно составить клетчатую доску: ПОВТОРИТЬ 8 РАЗ вертикальная полоса вправо (90) ^ вперед (5) влево (90) КОНЕЦ ' вправо (90) . назад (40) | влево (90) { Задача 7.5 Собственно доску рисуют те команды, что стоят внутри цикла. Три последние команды, стоящие вне цикла, возвращают Черепаху в исходное положение. Задача решена. Напишите программу рисования узора, изображенного на рисунке 7.5. Рис. 7.5 Длину стороны квадратов удобно выбрать равной 20. Мы не будем приводить полного решения этой задачи, но разобьем его на такие этапы, чтобы вам было легко продвигаться вперед. Стрелочкой на рисунках показано положение Черепахи. Переходите к следующему этапу только после того, как справились с предыдущим. Этап 1. Пишем процедуру рисования квадрата со стороной 20: Этап 2. Перемещаем Черепаху в середину правой стороны квадрата: 98 ГЛАВА Этап 3. Поворачиваем Черепаху на 45°: Этап 4. Пользуясь готовой процедурой, рисуем косой квадрат: Этап 5. Перемещаем Черепаху в противоположный угол косого квадрата, удобно при этом двигаться по сторонам самого квадрата: Этап 6. Поворачивая Черепаху на 135°, ориентируем ее «на север»: Этап 7. Отступая назад на «полстороны квадрата», переводим Черепаху в положение «готова продолжать»: Этап 8. Продолжаем дальше как бы с самого начала. Вам остается перевести то, что было сказано выше, на язык команд Черепахи. Это очень похоже на перевод с русского на английский, только в данном случае мы переводим не на английский, а на «черепаший». Задача 7.6 Напишите программу рисования вложенных квадратов (рис. 7.6). Рис. 7.6 Черепаха 99 6. Рисуем треугольник Задача 7.7 Решение Задача 7.8 Задача 7.9 Напишите программу рисования равностороннего треугольника со стороной 40. Конечное положение Черепахи должно совпадать с начальным (рис. 7.7). Наша главная трудность — понять, на сколько градусов следует поворачивать Черепаху в каждом углу. В помощь себе давайте придумаем новый персонаж — Ленивую Черепаху. Ленивая Черепаха понимает те же самые 6 команд, что и обычная. Но исполняет она только команды поворота влево и вправо. Все остальные команды она игнорирует, как будто их и не было. Она никуда не двигается, ничего не рисует и всегда находится в одном и том же месте. Но все повороты она исполняет точно так же, как обычная Черепаха. Поэтому она всегда повернута в ту же сторону, что и обычная Черепаха. Черепаха, рисующая треугольник, должна повернуться 3 раза — в трех вершинах треугольника. Значит, и Ленивая Черепаха повернется 3 раза на одном месте. Все повороты одинаковые. В сумме должен получиться поворот на 360°. Следовательно, каждый из трех поворотов равен 360°/ 3 = 120°. Вот мы и получили нужную нам программу; опусти хвост ПОВТОРИТЬ 3 РАЗ вперед (40) вправо (120) КОНЕЦ Напишите программу рисования «стоячего треугольника» (рис. 7.8) и оформите ее в виде процедуры под названием треугольник. Пользуясь процедурами квадрат и треугольник, напишите программу рисования домика (рис. 7.9). Рис. 7.7 Рис. 7.8 Рис. 7.9 100 и '( Задача 7.10 Черепаха выполнила такую программу: ПОВТОРИТЬ 10 РАЗ треугольник вправо (60) КОНЕЦ Что она нарисовала? Ленивая Черепаха помогает рисовать многоугольники и звезды 7. Задача 7.11 Напишите программу рисования правильного 7-угольника со стороной 15. Слово «правильный» означает, что у него все стороны равны и все углы равны. Решение Мы уже заранее знаем, как должна выглядеть наша программа: опусти хвост ПОВТОРИТЬ 7 РАЗ вперед (15) ‘ вправо (...?...) ^ КОНЕЦ Единственное, что нам пока неизвестно, — на какой угол поворачивать. Здесь снова приходит на помощь Ленивая Черепаха. Исполняя нашу программу, она повернется 7 раз на один и тот же угол, а в сумме это должно составить 360°. Значит, каждый поворот равен 360°/7. Прямо в таком виде, не вычисляя, его можно вставить в программу (только значок «градус» надо убрать). Задача 7.12 Напишите программу рисования: а) правильного 5-угольника; б) правильного 6-угольника; в) правильного 8-угольника; г) правильного 9-угольника; д) правильного 17-угольника. Теперь перейдем к рисованию звезд. 101 Задача 7.13 Решение Напишите программу ды (рис. 7.10). рисования 5-конечной звез- Понаблюдаем внимательно за поворотами Ленивой Черепахи в моменты, когда Черепаха проходит вершины лучей звезды. Мы убеждаемся в том, что она делает не один, а два полных оборота, т. е. поворачивается в сумме на 2 • 360° = 720°, Поскольку вершин всего 5, на каждый поворот приходится 720°/5 = 144°. Пробуем программу опусти хвост ПОВТОРИТЬ 5 РАЗ вперед (40) вправо (144) КОНЕЦ Задача 7.14 Задача 7.15 а) * Мы в самом деле получили звезду, но слегка повернутую (рис. 7.11). Чтобы получить звезду в правильном положении, нужно в самом начале программы повернуть Черепаху вправо на 18° — проверьте! Напишите программу, рисующую 8-конечную звезду (рис. 7.12). Черепаха выполнила такие программы: ------1 опусти хвост ПОВТОРИТЬ 7 РАЗ вперед (40) вправо (2*360/7) КОНЕЦ б) опусти хвост ПОВТОРИТЬ 7 РАЗ вперед (40) вправо (3*360/7) КОНЕЦ Что она нарисовала? > < м Рис. 7.10 Рис. 7.11 Рис. 7.12 102 ГЛАВА / 8. Рисуем окружность Черепаха, как и Чертежник, умеет рисовать только прямолинейные отрезки. Поэтому нарисовать точную окружность она не сможет. Но если начертить, например, правильный 120-угольник или тем более правильный 360-угольник, то его на глаз невозможно будет отличить от окружности. Только сторону многоугольника нужно брать очень маленькую. Например, так (программа справа). Может быть, вы помните, что в программе рисования Чертежником параболы нам пришлось вычислять много разных координат, а здесь мы обошлись без этого. опусти хвост ПОВТОРИТЬ 120 РАЗ вперед (1) вправо (3) КОНЕЦ ^Другие картинки Вы уже догадались, что с помощью Черепахи можно рисовать много разных картинок. Вы с успехом можете придумывать их сами. Вот вам еще несколько примеров. Задача 7.16 Напишите программы рисования картинок, изображенных на рисунке 7.13. а) б) ж ж ж ж ж 7 Рис. 7.13 Удобные размеры выберите сами. ИТОГИ Черепаха еще один графический Исполнитель. В отличие от Чертежника Черепаха имеет возможность работы с углами. Поэтому с ее помощью легко рисовать правильные многоугольники и звезды, а также поворачивать готовые картинки. Однако Черепаха не умеет пользоваться координатами, и поэтому ей трудно попасть в нужную точку. Глава 8 С 1 Ханойская башня ТТ| Правила игры Эта головоломка — любимая игра программистов: ее можно найти во многих программистских книжках. Несколько кружков разных размеров уложены друг на друга, образуя башню. Башня стоит на одном из трех полей. Задача — переставить ее на другое поле (рис. 8.1). Но просто переставлять башню неинтересно — никакой задачи тут нет. Чтобы задание было не таким простым, нужны какие-то правила. Вот они: 1) кружки переставляются с одного поля на другое, при этом их укладывают друг на друга, так что получаются маленькие башни. Нельзя откладывать кружки в сторону или ставить один кружок вместо другого; Рис. 8.1 104 Г л л Р, А Г 2) при каждом ходе двигается только один кружок. Нельзя переносить несколько кружков одновременно. Например, запрещено брать по кружку в каждую руку; 3) можно брать кружок лишь с вершины какой-нибудь башни и класть его только на вершину другой башни. Нельзя брать кружок из середины башни или вставлять его в середину другой башни; 4) запрещено класть больший кружок на меньший. Посмотрите на рисунки, где изображено несколько разрешенных и несколько запрещенных ходов. Так можно: 11, 4 Так можно: Так можно: Так нельзя: Так нельзя: Иногда, вместо того чтобы формулировать правило 3, в центры полей вставляют штыри, а в центрах всех кружков делают отверстия; потом кружки надевают на штыри — получаются детские пирамидки, Мы решили явно сформулировать это правило, потому что если у вас нет фабрично изготовленной пирамидки, то вы можете изготовить игру самостоятельно из монет, картонных кружков или даже из тарелок и блюдец. Возьмите башню из 4 или 5 кружков и поиграйте с ней. А мы пока расскажем вам легенду. 2Т| Легенда Эту игру изобрел французский математик Люка больше ста лет назад, в 1883 году. И он сам украсил ее романтической легендой. Где-то в непроходимых джунглях, недалеко от города Ханоя, есть монастырь бога Брамы. В начале времен, когда Брама создавал Мир, он воздвиг в этом монастыре три высоких алмазных стержня и на один из них возложил 64 диска, сделанные из чистого золота. Он приказал монахам перенести эту башню на другой стержень (в соответствии с правилами, разумеется). С этого времени монахи работают день и ночь. Когда они закончат свой труд, наступит конец света. 3. Рекордные результаты Надеемся, вы уже успели поиграть в эту игру, А теперь можно устроить небольшое соревнование. Возьмите башни из 1, 2, 3, ... кружков и попробуйте перенести их на другое поле за наименьшее число ходов. Самый первый результат абсолютно очевиден: если наша беппня сделана из одного кружка, то мы можем перенести ее за один ход. Получить рекорд для двух кружков тоже очень легко: нужно 3 хода. Чем выше башня, тем труднее перенести ее на другое поле за наименьшее число ходов. Надеемся, что после нескольких попыток вы придете к такому же результату, что и мы (см. таблицу). 106 ГЛАВА 8 Таблица мировых рекордов при игре в Ханойскую башню Число кружков Число ходов 1 1 2 3 3 7 4 15 5 31 Посмотрим повнимательнее на получившуюся числовую последовательность: 1, 3, 7, 15, 31, ... . Задача 8.1 Первое решение Попробуйте угадать правило (или формулу), которому подчиняется эта последовательность. Вопрос можно понять так: «Как узнать очередное число последовательности, зная предыдущее?» Тогда нетрудно увидеть, что нужно умножить предыдущее число на 2 и прибавить 1: 3 = 2 1 + 1 7 = 2' 3 + 1 15 = 2 ■7+1 31 = 2 15+1 Вспомнив Удвоитель из главы 1, мы можем записать эту закономерность в виде программы: Команда Число 1 умножь на 2 2 прибавь 1 3 умножь на 2 6 прибавь 1 7 умножь на 2 14 прибавь 1 15 о ойская башня 107 Обозначая п-е число через а„, получаем формулу Второе решение Oj = 1 02 = 2 • Cj + 1 Og = 2 • 02 + 1 «« + 1 = 2 ■ о„ + 1 Вопрос можно понимать и так: «Как получить л-е число непосредственно из числа л?* Тогда мы можем воспользоваться следующим наблюдением. Выпишем степени числа 2: 21 = 2; 2^ = 4; 2^ = 8; 2“* = 16; 2^ = 32. Легко заметить, что, вычитая 1 из этих чисел, мы получаем нашу последовательность; 1 = 2’ - 1 3 = 2^ - 1 7 = 2^ - 1 15 = 2'* - 1 Связь между двумя решениями Задача 8.2 а„ = 2'‘ - 1 Мы видели, что начала последовательностей, получаемых по обеим формулам, совпадают. А что произойдет дальше? Чтобы ответить на этот вопрос, возьмем из второго решения формулу а„ = 2" - 1 и подставим ее в формулу из первого решения: “«+1 = 2 • а„ + 1. Получим а„+1 = 2-(2"-1)-Ь1 = 2-2"-2-Ь1 = 2"^* - 1, а это совпадает с формулой из второго решения. Таким образом, если у последовательностей совпадают л-е элементы, то у них совпадают и (л-Ы)-е элементы. Значит, обе формулы определяют одну и ту же последовательность. Предскажите минимальное число ходов для башен из: а) 6; б) 7; в) 8 кружков. 108 Комментарий Мы пока не знаем, могут ли наши рекорды быть побиты. Ситуация очень интересная. Возьмем, к примеру, башню из 5 кружков. Доказать, что ее можно перенести за 31 ход, легко: просто перенести, и все. Но как доказать, что ее нельзя перенести за 30 (или даже меньшее число) ходов? Вы можете пробовать полчаса, или день, или даже целый год. Но если вам не удастся добиться успеха, то это ни о чем не говорит. Чтобы доказать, что что-то невозможно, нужно какое-то математическое рассуждение. Математики называют такое рассуждение доказательством невозможности. Мы слегка касались этого предмета в главе 1 и вернемся к нему в данной главе. А пока мы просто просим вас поверить, что выписанные выше рекорды побить нельзя. Итак, если монахи монастыря Брамы достаточно умны, то они закончат работу за (2®'* - 1) шагов. Задача 8.3 Решение Предположим, что монахам требуется 1 секунда на выполнение одного хода игры. Оцените приблизительно, сколько времени понадобится им для выполнения всего задания. Или, если вам так больше нравится, сколько времени должно пройти от Начала до Конца Света? Мы знаем, что 2'° = 1024 == 1000 = 10®. Тогда 2бо = (2^Y « (10®)® = 10^®. Это число называется квинтильоном, в нем единица и восемнадцать нулей. Следовательно, 2^4 = 2* ■ 2®® = 16 • 2®® ~ 16 • 10^®, т. е. число ходов (или секунд) приблизительно равно шестнадцати квинтильонам. На самом деле мы его недооценили, потому что мы заменили число 1024 меньшим числом 1000. В одних сутках 24 часа, в часе 60 • 60 = 3600 секунд. Значит, в сутках 24 ■ 3600 = 86 400 секунд, а в году в 365 раз больше, т. е. приблизительно 32 миллиона, или 32 ■ 10® секунд. 109 Проделав точные вычисления, вы убедитесь, что мы слегка переоценили это число. А теперь, чтобы узнать, сколько лет необходимо монахам, нужно разделить одно из полученных нами чисел на другое: (16 • 10‘V(32 • 10®) = 0,5 • 10‘^ = 500 000 000 000 лет. Мы недооценили числитель и переоценили знаменатель, поэтому настоящее значение будет даже больше. Так что если вас и беспокоил немного наступающий конец света, то отдохните — пока волноваться не о чем, пятьсот миллиардов лет — срок достаточно большой. Задача 8.4 Забудем про монахов. Представим себе, что какой-нибудь будущий Суперкомпьютер выполняет наилучшую возможную программу. И он может совершать в секунду один миллиард переносов дисков. Сколько времени понадобится компьютеру, чтобы переложить башню из 64 кружков? Решение Компьютер работает в миллиард раз быстрее мона- хов, поэтому ему понадобится в миллиард раз меньше времени — всего 500 лет. Вот прекрасный пример не очень сложной на первый взгляд задачи, решение которой недоступно даже наилучшим и наимощнейшим компьютерам. Вспомните это, когда кто-нибудь будет говорить о всемогуществе компьютеров! 4.1 Программа Теперь, кажется, неплохо было бы записать каким-нибудь образом решение головоломки — последовательность ходов в ней. Для этого нам необходимо изобрести способ записи ходов. Прежде всего обозначим поля слева направо латинскими буквами А, В и С. Назовем нашего первого Исполнителя Монах I. Введем несколько команд с одним аргументом для обозначения переноса кружка. Типичная команда выглядит так: перенеси с А на В (<кружок>) 110 ГЛАВА 8 По этой команде Исполнитель переносит кружок с номером, указанным в аргументе, с поля А на поле В. Остальные команды соответствуют другим парам полей. Упражнение Выпишите все команды Исполнителя Монах I. Сколько их? Упражнение Опишите ситуации, в которых может возникнуть ОТКАЗ. Кружки будем обозначать номерами 1, 2, 3, 4, ... , причем номер 1 обозначает самый маленький кружок, номер 2 — следующий и т. д. Теперь, договорившись об обозначениях, запишем программы для переноса башен из двух и трех кружков. Советуем снова взять башню и переносить кружки, записывая выполняемые действия. Вот что получается: перенеси с А на В (1) перенеси с А на С (2) перенеси с В на С (1) перенеси перенеси перенеси перенеси перенеси перенеси перенеси А на В (1) А на С (2) В на С (1) А на В (3) С на А (1) С на В (2) А на В (1) А вот и награда. Выписав эти две программы, мы видим, что первые три строчки второй программы повторяют первую программу. И кстати, обратите внимание на три последние строчки длинной программы. Что они означают? Ясно, что они переносят башню из двух кружков с С на В. Поэтому полезно заготовить две процедуры: ПРОЦ 2-башня с А на С НАЧАЛО перенеси с А на В (1) перенеси с А на С (2) перенеси с В на С (1) КОНЕЦ и ПРОЦ 2-башня с С на В НАЧАЛО перенеси с С на А (1) перенеси с С на В (2) перенеси с А на В (1) КОНЕЦ L^oi А теперь, используя эти процедуры, мы можем переписать программу для башни из трех кружков (пусть это тоже будет процедура!): Ханойская башня 111 Задача 8.5 Упражнение ПРОЦ 3-башня с А на В НАЧАЛО ‘ 2-башня с А на С перенеси с А на В (3) 2-башня с С на В КОНЕЦ Составьте таблицу состояний для этой программы. Напишите процедуру 3-башня с В на С. При необходимости используйте процедуры переноса меньших башен. Заготовив две процедуры для башни из трех кружков, мы можем написать процедуру для башни из четырех кружков: ПРОЦ 4-башня с А на С НАЧАЛО 3-башня с А на В перенеси с А на С (4) 3-башня с В на С КОНЕЦ Программа состоит из 3 строчек, но число ходов в ней 15: 3-башня с А на В 7 ходов перенеси с А на С (4) 1 ход 3-башня с В на С 7 ходов Действуя таким же образом, мы можем теперь решить нашу задачу для башни любого размера, даже задачу Брамы! 5. Решение задачи Брамы Оказывается, что нужная программа очень проста. Предположим, что сначала башня стоит на поле А: < башня из 64-х кружков > А В Мы хотим перенести ее на поле С. Сначала мы переносим меньшую башню из 63 кружков на поле В, используя процедуру 112 [f . й 63-башня с А на В Ситуация становится такой: < 64-й кружок > < башня из 63-х кружков > А В Следующее действие — перенос 64-го кружка: перенеси с А на С (64) И наконец, мы используем процедуру 63-башня с В на С и получаем такую ситуацию: < башня из 64-х кружков > А В Поэтому в нашей программе всего 3 строки: 63-башня с А на В перенеси с А на С (64) 63-башня с В на С Но мы еще не написали процедуры переноса башни из 63 кружков! Ну и что? Давайте напишем первую: ПРОЦ 63-башня с А на В НАЧАЛО 62-башня с А на С перенеси с А на В (63) 62-башня с С на В КОНЕЦ и т. д. Попробуем оценить общий объем работы, которую нам предстоит проделать. У нас встречаются башни 64 разных размеров, для каждой из них нам может понадобиться не больше 6 различных процедур (для переноса с А на В, с А на С и т. д.), в каждой я башня 113 процедуре 6 строк (считая строчки ПРОЦ, НАЧАЛО и КОНЕЦ). Поэтому всего нам надо написать не больше чем 64 • 6 • 6 = 2304 строки. Работа довольно большая. Но, конечно, на нее уйдет меньше пятисот миллиардов лет. Недели, пожалуй, хватит. Если бы мы умели работать с переменными, то могли бы написать одну процедуру вместо 64 • 6 = 192 процедур. И эта процедура оказалась бы совсем небольшой — не длиннее половины страницы. Замечательное достижение! 6. Три отступления Написав столько программ, давайте немного порассуждаем о них. 1. Алгоритм переноса дисков существует. С самого начала не было очевидно, что у задачи Брамы есть решение. Теперь же мы можем сказать: решение для башни из 6 кружков существует, потому что существует решение для башни из 5 кружков (мы используем его дважды, работая с башней из б кружков); а решение для башни из 7 кружков существует, потому что существует решение для башни из 6 кружков; ... ; а решение для башни из 64 кружков существует, потому что существует решение для башни из 63 кружков. Такой способ рассуждений называется рассуждением по индукции. 2. Обозначим минимальное число ходов для башни из л кружков через а„. Очевидно, 01 = 1. (п-Ь 1)-башню можно перенести за 2*а„-1-1 ход. Наша программа позволяет это сделать: перенести п-башню —► а„ ходов перенести кружок номер п + 1 -* 1 ход перенести п-башню —► а„ ходов Всего 2 • а„ -I- 1 ход 3. Башню нельзя перенести за меньшее число ходов. Действительно, перенести самый большой кружок можно, если выполнены два условия: на нем нет ни одного кружка и имеется пустое поле, на которое его можно поместить. Следовательно, все остальные кружки должны быть собраны на каком-то промежуточном поле. Минимальное количество ходов, необходимое для достижения такого расположения, мы обозначили через а„. Потом нужно положить самый большой кружок на свободное поле (1 ход), а затем собрать на нем все остальные кружки 114 ГЛАВА 8 (минимальное число ходов опять равно а„). Так что рекорд 2а„ + 1 нельзя побить, если предыдущий рекорд был а„. Начиная с очевидного рекордного результата Oj = 1, получаем а, = 2-1 + 1 = 3 Пз = 2 а. = 2 3 + 1 = 7 7 + 1 = 15 Другими словами, мы приходим к последовательности из раздела 3. 7^ Некоторые наблюдения Написанная нами программа оказалась очень простой и умной. Ее легко понять, но довольно трудно исполнить. Нужно все время держать в памяти, какие из вложенных одна в другую процедур выполняются в настоящий момент и на каком именно шаге происходит это исполнение. Если вы хотите сами поиграть в такую игру, а не обучать этому компьютер, то вам нужен алгоритм, более подходящий для человека. Следующие наблюдения, или правила, — не алгоритмы в точном смысле этого слова. Они не описывают, какой кружок и как передвигается на каждом шаге. Но они помогают ориентироваться в процессе игры. В конце концов, человек, в отличие от Исполнителя, может не только исполнять указания, но и 4|действовать согласно обстоятельствам». Некоторые из приводимых ниже правил можно преобразовать в алгоритмы, но это требует дополнительной работы. 1. Поведение самого маленького кружка. Посмотрев внимательно на процесс игры, вы увидите, что движение кружков подчиняется некоторым правилам: • каждая вторая команда переносит кружок 1; • он перемещается по кругу; например, начав со стержня А, двигается либо так: А—►В—►А — В—*С—>А—••В—*•... , либо так: А—►В — А-*С—►В—*А-»С—»... (рис. 8.2). Рис. 8.2 Мы можем считать, что с каждого поля есть два возможных хода — вправо и влево. При этом мы должны договориться, что Ханойс.ая башня 115 слева от поля А находится поле С, а справа от поля С находится поле А. Теперь команды Исполнителя можно придумать заново. Разумеется, получится другой Исполнитель. Назовем его Монах II. В новых командах мы будем задавать не два поля, а номер кружка и направление движения. Возможны два направления — вправо и влево. Поэтому получается всего две команды с одним аргументом. Например, команда перенеси влево (3) означает, что кружок номер 3 переносится влево: если он стоял на А, то окажется на С; если он стоял на В, то окажется на А; если он стоял на С, то окажется на В. Тогда последовательность ходов выглядит так: [ перенеси вправо (1) f I ? ? ? * I перенеси вправо (1) I I ? ? ? ■ I перенеси вправо (1) ? ? ? и т. д. Башню, состоящую из нечетного числа кружков, эта «программа* перенесет вправо, состоящую из четного числа кружков — влево. Если же мы хотим поступить наоборот, т. е. перенести башню из нечетного числа кружков влево, то мы должны отправить самый маленький кружок в обратном направлении: ' перенеси влево (1) j ? ? ? ' I перенеси влево (1) ? ? ? перенеси влево (1) и т. д. Слово «программа* взято в кавычки, потому что написанное нами еще не программа. Там пропущены команды, обозначенные знаками вопроса. 2. Поведение кружков 2, 3, 4, 5.Предположим, что верхние кружки на полях имеют номера 1, 2 и 3, как на рисунке 8.3, и мы не хотим двигать кружок 1: 116 ГЛАВА 8 11 Легко видеть, что тогда у нас есть всего одна возможность: положить кружок 2 на кружок 3. Правила запрещают класть кружок 2 на кружок 1, или кружок 3 на кружок 1, или кружок 3 на кружок 2. То же самое верно и в любой другой ситуации: движение не самого маленького кружка определено однозначно! Объясните почему. Остается неясным, какие команды следует подставить вместо знаков вопроса в тексты написанных выше ♦ программ». Но на самом деле, видя кружки своими собственными глазами, вы без труда выберете правильный ход. Еще одно наблюдение о кружках 2, 3, 4, ... гласит: • все кружки перемещаются по кругу; кружки 1, 3, 5, ... все время двигаются в одном направлении, а кружки 2, 4, 6, ... — в противоположном. 3. Раскрашенные кружки. Покрасим кружки 1, 3, 5, 7, ... , скажем, в желтый цвет, а кружки 2, 4, 6, ... в красный. Тогда выполняется следующее правило: • никогда желтый кружок не оказывается на желтом, а красный — на красном. Это правило поможет вам, если вы собьетесь в середине игры. Но одно оно не дает достаточной информации для однозначного определения последовательности ходов. Недостающую информацию мы можем получить, добавив такое простое правило: ни один кружок не двигается 2 раза подряд. 4. Дзэн-алгоритм *. Дзэн-буддизм — ветвь восточной философии, религия и мировоззрение. Среди эстетических ценностей Дзэн подчеркивает значение Этот алгоритм мы узнали от его автора, польского математика и психолога А. Лисовского. Я башня 117 тишины и пауз в музыке, невысказываемого в поэзии, пустого пространства в изобразительном искусстве. В Ханойской башне из него вытекает необходимость внимания к нетронутым полям. В каждом ходе участвуют два поля: поле, с которого мы берем кружок, и поле, на которое мы его кладем. Третье поле никакой роли в этом ходе не играет. Мы будем называть его нетронутым полем. Например, если мы перемещаем кружок с поля А на поле В, то поле С нетронутое. Глядя на последовательность нетронутых полей, мы замечаем, что: • нетронутые поля меняются по кругу. Например, перенося 4-башню с поля А на поле С, вы получите такую последовательность нетронутых полей: С, В, А, С, В, А, С, В, А, С, В, А, С, В, А. Кстати, когда известно нетронутое поле, ход определен однозначно. Действительно, если поле С нетронутое, то мы переносили кружок либо с поля А на поле В, либо с поля В на поле А. Но только один из этих ходов можно сделать по правилам — тот, при котором меньший кружок оказывается на большем. Поэтому последнее правило тоже дает человеческий алгоритм: последовательность ходов однозначно определена, и человек может ее проделать, просто глядя на башни. Теперь мы можем придумать нового Исполнителя Монах III. У этого Исполнителя будет три команды: перенеси не трогая А перенеси не трогая В перенеси не трогая С Процедура для переноса, например, башни из 4 кружков с поля А на поле С будет совсем простой: ПРОЦ 4-башня с А на С НАЧАЛО ПОВТОРИТЬ 5 РАЗ перенеси не трогая С перенеси не трогая В перенеси не трогая А КОНЕЦ КОНЕЦ 118 ГЛАВА 8 Задача 8.6 Напишите процедуру переноса с поля А на поле С башни из 6 кружков и башни из 7 кружков. 5. Последовательность номеров кружков. Запишем номера кружков в том порядке, в котором они двигаются. Число кружков в башне 1 2 3 4 5 Номера передвигающихся кружков 1 121 1213121 121312141213121 1213121412131215121312141213121 Правило очень простое. Если мы хотим, например, записать 7-ю строку, то мы должны взять 6-ю строку, приписать к ней число 7 и еще раз повторить 6-ю строку. Эту последовательность легко продолжить до бесконечности. У нее много интересных свойств. Она связана с такой замечательной темой, как знаменитая «Кривая Дракона», а также с максимальными степенями числа 2, делящими натуральные числа. Но мы не будем сейчас в это углубляться. И последнее замечание. В разделах 4 и 5 мы написали программу, решающую головоломку о Ханойской башне. С помощью правил этого раздела мы можем написать еще по крайней мере три другие программы. Мы не будем делать этого, однако отметим интересное свойство игры: все четыре программы совершенно различны, но при исполнении дают одну и ту же последовательность ходов. ИТОГИ в этой главе мы познакомились с головоломкой о Ханойской башне. Мы написали программу решения этой головоломки и доказали, что она наилучшая из возможных. Мы подсчитали число шагов в ней. Мы также сделали много важных наблюдений. Игры и головоломки — восхитительный мир для применения программирования и развития алгоритмического мышления. Глава 9 Г' в ' ' ‘i л» ..... ■ 1 г-г-'- А L.^1 • А— Невозможность I I Иногда мы не можем написать нужную программу не потому, что недостаточно умны, а потому, что такая программа просто не существует. В этой главе мы приведем несколько примеров подобной ситуации и прокомментируем их. Бывает, что невозможность просто очевидна, как в следующем примере. Предположим, что нам требуется перевести Робота в точку D (рис. 9.1). Древние ученые в таком случае рисовали картинку и писали рядом с ней: «Смотри». Но часто ситуация оказывается не столь простой. Между прочим, мы уже затрагивали эту тему в предыдущих главах. Мы обсуждали вопрос, можно ли переместить башню из 5 кружков меньше чем за 31 ход. И тогда мы также наталкивались на самое загадочное свойство результатов о несуществовании, а именно: доказывая существование чего-либо, вы можете это что-либо просто предъявить. Но если вы доказываете несуществование чего-либо, то чем вы можете пользоваться? Например, чтобы доказать, что носорог существует, достаточно всего лишь показать носорога. Но представьте себе, что вам нужно доказать, что не существует единорога.. Какие доводы вы будете приводить? Никто не видел единорога? Ну и что? Возможно, они просто здорово прячутся. Только рассуждения могут нам помочь. А вот другой пример. У Кузнечика две команды: вперед 4 и назад 2 Рис. 9.1 120 ГЛАВА 9 Может ли он добраться из точки О в точку 7? Попробуйте попрыгать вместе с Кузнечиком. Скоро вы увидите, что он может попасть в точки О, 2, 4, 6, 8, , а в точки 1, 3, 5, 7, ... не может. Другими словами, ему доступны лишь четные числа. Почему? Потому что, вычитая и прибавляя числа 4 и 2, мы можем получить только четные числа. Поэтому на вопрос «Может ли Кузнечик попасть из точки О в точку 7?» правильный ответ: нет. Метод, который мы только что изобрели, оказывается очень мощным. Он называется методом инвариантного утверждения. Слово «инвариант* означает «что-то, что не меняется при любых обстоятельствах*. Пока происходят различные события и состояние Исполнителя меняется, инвариантное утверждение по-прежнему остается истинным. В нашем примере инвариантное утверждение выглядит так: «Позиция Кузнечика имеет четный номер». Оно верно в самом начале, когда Кузнечик находится в точке 0. Если это утверждение верно перед выполнением команды вперед 4, то оно остается верным и после выполнения этой команды (потому что прибавление 4 к четному числу опять дает четное число). То же справедливо и для команды назад 2: если номер позиции четен перед ее выполнением, то он четен и после этого. Следовательно, утверждение остается верным во время всего выполнения любой программы и после окончания ее выполнения. Задача 9.1 Задача 9.2 У Водолея две емкости: 4-литровая и 6-литровая. Может ли он отмерить 3 литра воды? На столе вверх дном стоят семь стаканов. За один шаг разрешается переворачивать ровно два стакана. Можно ли привести все стаканы в правильное положение? Приведем еще один пример. Робот стоит в левом нижнем квадрате А прямоугольного поля. Нам нужно, чтобы он оказался в правом верхнем квадрате В, побывав в каждом квадрате в точности по одному разу. Два возможных решения для полей 3 X 3 и 3 X 4 показаны на рисунке 9.2. Для поля 2x2 решения, очевидно, не существует: из А в В идет всего два пути и оба упускают один квадрат. Рис. 9.2 ' В \ гг" А I Невозможность 121 В А Попробуем теперь поле 4X4. После нескольких попыток кажется, что решения не существует. Но из А в В ведет слишком много путей, и с уверенностью сказать трудно. А как насчет поля 8X8? Попытайтесь! Раскрасим поле 8X8, как шахматную доску (рис. 9.3). Тогда инвариантно следующее утверждение: *Или число ходов Робота четно, и Робот стоит на черном квадрате; или число ходов Робота нечетно, и Робот стоит на белом квадрате*. Действительно, в самом начале утверждение верно: число шагов четно (оно равно 0) и Робот стоит на черном квадрате А. Предположим теперь, что мы сделали несколько шагов, и утверждение по-прежнему остается верным. Сделаем еще один шаг. Если число шагов было четным, то оно станет нечетным; и если Робот был на черном квадрате, то он попадет на белый квадрат. Утверждение остается по-прежнему верным. Другой случай рассматривается так же. Чтобы посетить каждый квадрат в точности один раз, нам нужно сделать 63 шага. Последний квадрат должен при этом быть белым. Поэтому им не может оказаться квадрат В. Рис. 9.3 Упражнение Задача 9.3 Раскрасьте поля 3 х 3, 3 х 4, 2 х 2, 4 х 4, как шахматные доски. Сосчитайте необходимое число шагов для каждого случая. Удовлетворяют ли результаты нашему инвариантному утверждению? Может ли шахматный конь пройти с поля А на поле В, побывав на всех полях в точности по одному разу? В дальнейшем вы увидите, что метод инвариантного утверждения пригоден не только для того, чтобы разрушать наши надежды. Куда чаще его приходится применять для построения очень сложных и защищенных от ошибок программ. Он также полезен для исследования игр и придумывания стратегий. Мы сможем писать программы для игр только после того, как познакомимся с переменными и командами ввода-вывода, а это случится во второй части книги. Но пока один пример. На прямоугольной доске в левом нижнем углу стоит шахматная ладья. Она может двигаться вверх или вправо, но не вниз или влево. Два игрока поочередно делают ход ладьей. Игрок, который приведет ее в клетку В, выигрывает (рис. 9.4). Как нужно играть? 122 Рис. 9.4 — - — - ■ а А а Выигрывающая стратегия состоит в том, чтобы прийти на диагональ, выходящую из клетки В, и каждым очередным ходом возвращаться на эту диагональ. Это то же самое, что оставлять инвариантным следующее утверждение: «После моего хода ладья на диагонали: после хода противника ладья не на диагонали*. Упражнение Объясните, почему эта стратегия приносит победу. Таким образом, на квадратной доске выигрывает второй игрок, а если размеры сторон доски различны, то первый. Конечно, мы предполагаем, что оба играют в соответствии с выигрышной стратегией. Если они делают ошибки, то невозможно предсказать, кто победит. Задача 9.4 Два игрока играют в такую игру. У них два кошелька с монетами, и они по очереди достают монеты из кошельков. Разрешается всякий раз взять любое число монет, но только из одного кошелька. Игрок, берущий последнюю монету (т. е. оба кошелька остаются пустыми после его хода), выигрывает. Найдите выигрывающую стратегию. Подсказка Данная задача тесно связана с задачей про ладью на прямоугольной доске. На самом деле речь идет об одной и той же задаче! Обдумайте это. Метод инвариантного утверждения, конечно, не единственный способ доказательства невозможности. Вернемся к последнему примеру с Роботом и рассмотрим поле размером 2X4 (рис. 9.5). Мы можем нарисовать все пути, когда Робот не заходит дважды на одно и то же поле и останавливается только тогда, когда ходов уже нет. Рис. 9.5 1ГГ-Т' I --4J .1) !1"Г! '£ г Г' - 1 Не зможность 123 Упражнение Нарисуйте все такие пути. Общее число путей равно 11. Когда вы нарисуете их все, вы увидите, что каждый путь либо не проходит через все квадраты, либо не кончается в точке В, либо и то и другое. Метод, который мы только что применили, называется методом полного перебора. Обычно он требует очень большого труда. А теперь попробуем разобраться, можно ли поставить мат черному королю, если у белых есть король и слон. Ответ: нет. Для доказательства не требуется перебирать все возможные расположения трех фигур. Достаточно рассмотреть три ситуации: • черный король в углу; • черный король у края, но не в углу; • черный король не у края доски. В третьем случае черный король может пойти на 8 полей. Белый король в состоянии помешать ему передвинуться не больше чем на 3 поля, а слон — не больше чем на 2 поля. Поэтому мат в таком положении невозможен. Во втором случае у короля всего 5 возможностей для хода, а не 8, но слон может при этом закрыть только одно поле. Упражнение Рассмотрите сами случай черного короля, стоящего в углу. Закончим эту главу, упомянув еще один метод доказательства невозможности, а именно метод промежуточной ситуации. На самом деле мы его уже использовали при обсуждении Ханойской башни. Напомним его. Если мы хотим переместить башню из 5 кружков с поля А на поле В, то в какой-то момент нам придется перенести кружок номер 5 с поля А на поле В. Чтобы иметь возможность это сделать, нам необходимо: • очистить поле В; • снять башню с кружка номер 5. Как следует из этих двух требований, башня из 4 кружков должна стоять на поле С (рис. 9.6). Рис. 9.6 В 124 ГЛАВА 9 Такое положение кружков обязательно встретится. Теперь можно рассуждать о том, что было сделано до этого и что должно быть сделано после. Подобное рассуждение применяется в следующей задаче: Задача 9.5 Четыре рыцаря и четыре оруженосца подошли к берегу реки... Продолжение этой истории в точности совпадает с задачей из раздела 8 главы 1: в маленькую лодку помещается только два человека; однако каждый оруженосец отказывается оставаться на берегу или в лодке с другими рыцарями, но без своего хозяина. Могут ли восемь людей переправиться через реку? Рыцари и оруженосцы переправиться не могут, хотя доказать это довольно трудно. Мы приведем основную идею. Посмотрим на такую промежуточную ситуацию; первый ход, после которого на противоположном берегу оказалось больше двух рыцарей. Очевидно, нельзя решить задачу, миновав эту ситуацию. Далее можно рассуждать так: на этом ходе в лодке переправлялось не больше двух человек. Поэтому в лодке было либо два рыцаря, либо один рыцарь (может быть, с оруженосцем). Какие могут быть состояния? Надеемся, теперь вы справитесь с задачей самостоятельно. Задача 9.6 Двое играют в следующую игру. У каждого из них по мешку одинаковых круглых монет. Они по очереди кладут монеты на свободное место на круглом столе. За край стола вылезать нельзя. Если при очередном ходе свободного места для монеты нет (т. е. монета накладывается на уже положенную монету), то сделавший последний (правильный) ход выигрывает. Какой из игроков выигрывает при правильной игре — тот, кто делает ход первым, или другой? Как он должен играть? Что изменится, если стол будет прямоугольным? ИТОГИ Мы узнали, что бывают такие ситуации, когда нам не удается решить задачу просто потому, что решения не существует. В этих случаях решить задачу — значит доказать, что решения действительно нет. Мы познакомились с двумя методами проведения таких доказательств: методом инвариантного утверждения и методом полного перебора. Здесь же мы впервые встретились с игровыми алгоритмами и понятием стратегии игры. Глава 10 П Xi LI т Директор строительства: краткое введение в параллельное программирование В наши дни словосочетание «параллельное программирование» чрезвычайно популярно среди программистов и звучит очень современно. Но у этого термина немало предшественников в обыденной жизни, что, как мы видели в предыдущих главах, случается нередко. Параллельное программирова ние — это работа нескольких Исполнителей. Они делают общее дело. При этом они могут работать как последовательно, так и одновременно, или, как принято говорить, параллельно. Результат зависит от их взаимодействия. На рисунке 10.1 вы видите какое-то здание, сделанное из кубиков. Можете считать, что это дворец. Кубики помечены числами. Представьте себе, что вы Директор строительства. В вашем распоряжении несколько строительных бригад, и вы должны давать им работу. Давайте установим правила игры. • Всякий блок (кубик) независимо от своего вида и размера устанавливается одной бригадой за один день. Две бригады не могут устанавливать один и тот же блок. 126 • Строительство блока можно начать только после того, как установлены все блоки, на которые он опирается. Установка блока 3 возможна только после того, как закончена работа над блоками 1 и 2. Блоки же 3 и 11 дают другой пример. Они «независимы». Устанавливать блок 3 можно до или после блока 11 и даже в один день, если в вашем распоряжении больше одной бригады. Каждая бригада является Исполнителем. У такого Исполнителя всего одна команда: установи (<номер>) Вместо слова <номер> необходимо поставить номер какого-нибудь блока. Задача 10.1 Упражнение У вас только одна бригада. Напишите программу строительства дворца на рисунке 10.1. Сравните ее с программами, приведенными в следуюш;ем упражнении. Вот три разные программы решения задачи 10.1. Две из них правильные, а в одной есть ошибка. Найдите неправильную программу и укажите в ней ошибку. установи установи установи установи установи установи установи установи установи установи установи установи (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) установи установи установи установи установи установи установи установи установи установи установи установи (1) (2) (9) (10) (3) (11) (12) (4) (6) (5) (7) (8) установи установи установи установи установи установи установи установи установи установи установи установи (10) (12) (1) (2) (3) (6) (5) (9) (4) (7) (8) (11) Сколько времени нужно на выполнение всей работы? Конечно, все строительство займет 12 дней. И в этом нет ничего удивительного — ведь дворец состоит из 12 блоков. Изменим условие задачи. Директор ст р о и т е п ь ст Е а: краткое введение 127 в параллельное программирование Задача 10.2 У вас теперь сколько угодно бригад. Постройте дворец за наименьшее возможное время. Мы пока еще не договорились об обозначении одновременной работы нескольких бригад. Давайте сделаем это. СИНТАКСИЧЕСКОЕ ПРАВИЛО Если одновременно работают несколько бригад, то мы будем записывать команды для них на одной строке, разделяя их точкой с запятой. Вернемся к нашей задаче. Ответ Вот одна из таких программ: установи (1); установи (2); установи (9); установи (10) установи (3); установи (11); установи (12) установи (4); установи (6) установи (5) установи (7) установи (8) Такой программе требуется 4 бригады. Даже если бы у нас было больше 4 бригад, мы не смогли бы обеспечить их работой. И нашим 4 бригадам тоже не хватает работы. Только одна из них работает все время, остальные простаивают половину времени или больше. Они теряют время, а директор — деньги. Но зато работа оказывается оконченной за 6 дней! Почему ее невозможно выполнить еще быстрее? (Гм! Невозможно... Невозможность... Где-то нам это слово попадалось, правда?) Рассуждать можно так. На рисунке 10.2 закрашена цепочка блоков 1, 3, б, 5, 7, 8. Эти блоки можно устанавливать только последовательно, один за другим. Значит, для их установки требуется по крайней мере б дней работы, даже если не обращать внимания на остальные части конструкции. Такую цепочку называют критическим путем. Критический путь может быть не единственным. Вместо блока 1 можно начать его с блока 2. Теперь может возникнуть следующий вопрос. Нам нужно установить 12 блоков, на что потребуется самое меньшее б дней. Так может быть, мы справимся с этим двумя бригадами, которые будут работать каждый день? 128 ГЛАВ Рис. 10.2 Задача 10.3 Постройте дворец за 6 дней с помощью только двух бригад. Это не так-то легко, не правда ли? Ответ Вот одна из таких программ: установи установи установи установи установи установи (1); установи (2) (3) ; установи (9) (4) ; установи (6) (5) ; установи (11) (7) ; установи (10) (8) ; установи (12) i Секрет в том, чтобы не пропускать блоки, лежащие на критическом пути. Например, в первый день надо непременно установить и блок 1, и блок 2 — они оба лежат на критических путях. Во второй день должен быть установлен блок 3. Другим блоком в этот день можно взять 9 или 10, но один из этих двух блоков нужен обязательно, иначе вторая бригада потеряет время! На третий день требуется установить блок 6; вторым блоком при этом выбирается 4, или 11, или 10; и т. д. Установку блока 4 пока можно было отложить, но если его не установить на четвертый день, то все наши планы провалятся. Значит, и сама программа способна создавать новые критические пути. Д и р ч : i :) о с о и г а л ь с т о а: к р а т к к' е--5 п а р а Л Л е Л ь н - , п о г ; а м ..1 t О е I и 129 Чтобы выделить «обязательные» блоки, перепишем программу еще раз, подчеркнув их при этом: установи установи установи установи установи установи (1); установи (2) (3) ; установи (9) (4) ; установи (g) (3); установи (11) (Z); установи (10) (3); установи (12) А теперь самое подходящее время заняться конструкцией, изображенной на рисунке 10.3. Задача 10.4 У вас всего одна бригада. Напишите программу для построения дворца на рисунке 10.3. Сравните свою программу с программами других учеников. Ваша программа требует 18 дней, потому что здание состоит из 18 блоков. Задача 10.5 У вас сколько угодно бригад. Напишите программу для самого быстрого возможного построения здания. Вам удалось справиться с работой за 9 дней, не так ли? 130 « I Задача 10.6 Найдите какой-нибудь критический путь длины 9. Итак, работу невозможно закончить быстрее чем за 9 дней. А теперь зададим тот же самый вопрос, что и раньше: раз у нас 18 блоков и 9 дней, то нельзя ли обойтись всего двумя бригадами? Попробуйте! Несколько неудачных попыток приводят нас к мысли, что задача неразрешима. Действительно, построить это здание за 9 дней всего двумя бригадами невозможно. Доказательство невозможности не очень простое. Обсудим его. • Посмотрим на блок 2. Его необходимо установить на второй день, иначе мы запоздаем. Но этот блок опирается на 3 блока: 1, 8 и 9; их невозможно установить все за первый день работы, если у вас всего 2 бригады. Вот первое препятствие, которое приводит к одному дню опоздания. • Далее посмотрим на блок 4. Нам хотелось бы установить его на шестой день, потому что над ним еще 3 этажа: блоки 5, 6 и 7. Мы уже опаздываем на один день, так что установим его лишь на седьмой день вместо шестого. Но после этого над блоком 4 осталось еще 7 блоков, а именно блоки 5, 6, 7, 13, 14, 16 и 17. Если у вас всего 2 бригады, то 7 блоков установить за 3 дня нельзя! Потребуется по крайней мере 4 дня. Поэтому всю конструкцию невозможно построить быстрее чем за 11 дней. Задача 10.7 Постройте конструкцию за 9 дней с помощью 3 бригад. Задача 10.8 Постройте конструкцию 2 бригадами за 11 дней. Давайте попробуем ответить на вопрос: какой план лучше? С подобными вопросами постоянно сталкивается директор в обычной жизни. Ответ: бывает по-разному. При выборе первого плана директор должен платить бригадам 3 • 9 = 27 дневных зарплат, а по второму плану должен платить 2 • 11 = 22 дневные зарплаты. Но, закончив работу на 2 дня раньше, он, конечно, получит какую-то выгоду. Если эта выгода превышает 5 дневных зарплат, то первый план лучше; если нет, то лучше второй план. У настоящих директоров проблем гораздо больше, но мы не будем сейчас в них углубляться. Лучше решим еще несколько задач. Задача 10.9 Изменим немного здание на рисунке 10.1, переместив его правое крыло внутрь (рис. 10.4). Можно ли теперь построить его двумя бригадами за б дней? Директор строительство: К; птк нведс:-:ие 131 в параллельное прог;, агу11иироваг:.те 1 2 3 Рис. 10.5 Задача 10.10 У Директора 2 бригады. Он хочет построить конструкцию, изображенную на рисунке 10.5, за 4 дня. Директор начал программу строкой установи (1); установи (2) Прав ли он? Можете ли вы ему помочь? Задача 10.11 Напишите программу строительства конструкции, приведенной на рисунке 10.6, за 6 дней тремя бригадами. 132 Г Л А L- г. 1 '' у двух последних задач есть одно интересное общее свойство: каждая из них имеет единственное решение. В первых примерах этой главы нам подходило несколько разных программ. Но в каждом из этих двух примеров такая программа всего одна. У нас нет выбора, что устанавливать в первый день, что во второй и т. д. Конечно, в одной строке порядок команд можно менять и писать вместо установи (3); установи (2) установи (2); установи (3) Но ведь при этом ничего не меняется, ми переставлять нельзя! Команды между строка- Задача 10.12 Докажите единственность решений в задачах 10.10 и 10.11. ИТОГИ в этой главе вы познакомились с взаимодействием Исполнителей. Такое взаимодействие позволяет решать трудные (а иногда и недоступные одному Исполнителю) задачи. Однако сама по себе эффективная организация подобного взаимодействия — сложная и интересная задача. Проектируйте и стройте ваши собственные дома! Глава 1 1 I I 1«1 [ Рекурсия • о ] [ В главе 9 мы уже встречались с задачами, решить которые невозможно. Однако бывают задачи, не поддаюш;иеся решению уже изученными нами методами, но их все же можно решить с помощью рекурсии. Рекурсия — универсальный метод программирования, применимый к любому Исполнителю. Знакомство с ней мы начнем на примере задач для Робота. Т. процедуры, вызывающие самих себя Задача 11.1 Робот стоит в горизонтальном прямоугольнике, ширина которого равна 1, огороженном стенами, на некотором расстоянии от левой стены. Переведите Робота в клетку, находящуюся на таком же расстоянии от правой стены (рис. 11.1). Робот стоит здесь Рис. 11.1 Решение Задача кажется совсем простой. Действительно, если мы знаем, что расстояние от Робота до левой стены, скажем, две клетки, то отправить его в нужную клетку не составляет труда: достаточно довести его до правой стены, а затем сделать два шага влево. Сложность, однако, заключается в том, что расстояние до левой стены может быть любым, а у нас нет ни способа измерить это расстояние, ни возможности использовать потом полученное значение. Выход, как это часто случается, оказывается неожиданным. Давайте начнем писать процедуру, решающую поставленную задачу. Назовем эту процедуру симметрия. В начале работы нам поможет то, что задачу несложно решить по крайней мере в одном случае: когда Робот стоит у левой стены. Тогда он просто должен дойти до правой стены и остановиться: 134 ПРОЦ симметрия НАЧАЛО ЕСЛИ НЕ слева свободно ТО ПОКА справа свободно ДЕЛАТЬ вправо КОНЕЦ ИНАЧЕ КОНЕЦ КОНЕЦ J Подумаем теперь над тем, что делать, если слева от Робота стены нет. Давайте сделаем шаг влево — расстояние от Робота до левой стены уменьшится. Может быть, оно даже станет нулевым! Но это означает, что процедура симметрия уже выполняет нужную работу и мы можем... вызвать ее саму. А по окончании ее выполнения следует сделать еще шаг влево, чтобы расстояние от Робота до правой стены было в точности равно расстоянию от его исходного положения до левой стены. Вот что получается: ПРОЦ симметрия НАЧАЛО ЕСЛИ НЕ слева свободно ТО ПОКА справа свободно ДЕЛАТЬ вправо КОНЕЦ ИНАЧЕ влево симметрия влево КОНЕЦ КОНЕЦ Оказывается, что написанная процедура работает правильно в любой ситуации! А программа, решающая поставленную задачу, выглядит совсем просто: симметрия В результате у нас получилась очень странная процедура: она вызывает саму себя. Такие процедуры называются рекурсивными. Давайте приглядимся к ней внимательнее и изучим ее работу шаг за шагом. Рекурсия 135 Мы уже проверили, что процедура работает правильно, когда начальное расстояние от Робота до левой стены равно нулю. Посмотрим, что произойдет, если сначала между Роботом и стеной будет одна клетка. Условие НЕ слева свободно в начале выполнения процедуры ложно, поэтому будет выполняться часть конструкции ветвления, следующая за словом ИНАЧЕ. В этой части три команды: влево симметрия влево Исполнив первую команду влево. Робот оказывается на одну клетку ближе к левой стене, т. е. у самой стены. Затем следует процедура симметрия. Но ситуация изменилась: Робот стоит у левой стены. Мы знаем, что в этой ситуации процедура работает правильно и Робот оказывается у правой стены. Команда влево отводит его на одну клетку от правой стены, при этом он попадает в нужную клетку, и выполнение процедуры заканчивается. Вы, наверное, уже поняли, как проверить правильность работы процедуры при начальном расстоянии Робота до левой стены в две клетки. Условие НЕ слева свободно ложно, и в процедуре выполняется часть конструкции ветвления, следующая за словом ИНАЧЕ. Исполнив первую команду влево. Робот оказывается на одну клетку ближе к левой стене, на расстоянии одной клетки от нее. Затем следует процедура симметрия, которая, как мы уже знаем, переводит Робота в клетку, расположенную на расстоянии 1 от правой стены. Следующий шаг влево переводит Робота в нужную клетку. Такой способ рассуждения — рассуждение по индукции — нам уже не раз встречался. Он позволяет проверить правильность работы процедуры и при любом другом начальном расстоянии от левой стены. Упражнение Упражнение Почему перед последней командой влево в процедуре симметрия можно не проверять условие слева свободно? Выпишите последовательность шагов Робота при выполнении процедуры симметрия для положений Робота, указанных на рисунке 11.2. а) Рис. 11.2 ] б) □ ч 136 ГЛАВА Задача 11.2 Робот находится в огороженном прямоугольнике. Внутри прямоугольника стен нет. Напишите программу, переводящую Робота в клетку, симметричную исходной относительно центра прямоугольника. Разберем еще одну задачу. Задача 11.3 Решение Робот находится в горизонтальном коридоре ширины 1. Слева коридор ограничен стеной, справа бесконечен. Переведите Робота в такую клетку, чтобы расстояние от Робота до левой стены стало вдвое больше начального. В этой ситуации опять понятно, что должен делать Робот, когда он находится вплотную к стене, — просто оставаться на месте: ПРОЦ двойной прыжок НАЧАЛО ЕСЛИ НЕ слева свободно ИНАЧЕ КОНЕЦ КОНЕЦ Какие команды надо вставить вместо многоточия? Во-первых, наверное, сначала необходимо уменьшить расстояние до стены — упростить ситуацию, т. е. выполнить команду влево. Затем снова вызвать процедуру двойной прыжок. Далее сделать два шага вправо, так как требуется, чтобы расстояние до стены увеличилось вдвое. Значит, каждому шагу влево должно соответствовать два шага вправо. Упражнение 1) Напишите процедуру двойной прыжок до конца. 2) Напишите другой вариант процедуры двойной прыжок, заменив проверку условия НЕ слева свободно проверкой условия слева свободно. 3) Выпишите последовательность шагов Робота при выполнении процедуры двойной прыжок, если начальное расстояние до левой стены равно: • двум клеткам; • трем клеткам. 137 2^ Выход из рекурсии Рекурсивные процедуры можно писать для любого Исполнителя. Напишем, например, процедуру рисования квадрата Черепахой. Задача 1 1.4 Напишите рекурсивную процедуру рисования квадрата со стороной 40. Ответ : ПРОЦ рекурсивный квадрат i t НАЧАЛО I вперед (40) ^ [ вправо (90) ' ; рекурсивный квадрат . КОНЕЦ Программа, вызывающая эту процедуру, выглядит так: опусти перо ' рекурсивный квадрат ‘ подними перо .1 Посмотрим, как работает эта программа. При вызове процедуры рекурсивный квадрат выполняются команды I вперед (40) i ; вправо (90) ! При этом Черепаха рисует сторону будущего квадрата и поворачивается на 90 градусов. Затем снова вызывается процедура рекурсивный квадрат. Черепаха рисует еще одну сторону квадрата и поворачивает направо. Далее следует новый вызов процедуры рекурсивный квадрат. Еще две стороны — и рисование квадрата закончено. Но что случилось? Черепаха не останавливается, она продолжает ходить по уже нарисованному квадрату, заново прочерчивая его стороны. Так продолжается бесконечно — происходит зацикливание. Команда подними перо в конце программы просто никогда не выполняется — до нее не доходит дело, и мы ее зря написали. Ситуация неприятная. Мы стремились всеми силами избегать зацикливания. Можем ли мы избавиться от него в данном случае? 138 ГЛАВА 11 Оказывается, нет. Действительно, чтобы вызовы рекурсивной процедуры не повторялись бесконечно, в процедуре нужно указать условия, при которых такого вызова не происходит. Однако у Черепахи нет условий! Программы Черепахи выполняются одинаково независимо от ее состояния. Точно так же отсутствуют условия у Исполнителей Крестьянин, Водолей, Кузнечик, Удвоитель, Чертежник, Монахи, Директор строительства. Использование рекурсивных процедур для этих Исполнителей приводит либо к зацикливанию, либо к возникновению ОТКАЗа, если очередную команду нельзя выполнить. Поэтому не применяйте рекурсивных процедур для Исполнителей, не имеющих условий. Из рассмотренных в нашей книге Исполнителей условия есть лишь у Раздвоителя и Робота. Значит, имеет смысл писать рекурсивные процедуры только для этих двух Исполнителей. Из нашего обсуждения можно сделать и другой вывод: • При написании рекурсивной процедуры необходимо указать условия, при которых рекурсивного вызова не происходит. Этот вывод очень важен! И совсем не случайно мы, приводя в предыдущем разделе примеры программ, начинали запись рекурсивной процедуры с указания этих условий и с описания необходимых действий. Задача 11.5 Укажите условия, при которых рекурсивного вызова не происходит, а также действия, которые необходимо при этом совершить, в следующих задачах: а) получение Раздвоителем нуля из любого числа; б) Робот стоит у горизонтальной стены, в которой есть проход, снизу от нее. Неизвестно, слева или справа от Робота находится проход. Найдите его; в) Робот стоит у горизонтальной стены снизу от нее. Слева от Робота в стене есть проход. Робот должен пройти через этот проход и оказаться над стеной рядом со своим начальным положением; г) сверху от Робота есть закрашенная клетка, стен на поле Робота нет. Переведите его в положение над закрашенной клеткой так, чтобы расстояние между Роботом и клеткой втрое превышало исходное. 139 3. Когда можно обойтись без рекурсии Несмотря на кажущуюся простоту, работать с рекурсией достаточно сложно. Действительно, вспомним наши первые программы для Крестьянина, Водолея, Кузнечика. Проверить их правильность было довольно просто: мы следили за состоянием Исполнителя после выполнения каждой команды и убеждались, что после исполнения всех команд программы состояние удовлетворяло условию задачи. Введение конструкции повторения не слишком усложнило проверку. Действия Исполнителя по-прежнему не зависели от его состояния. Единственная дополнительная трудность состояла в том, что даже при выполнении программы с очень короткой записью Исполнителю иногда приходилось совершать много действий. Совсем по-другому отражается на проверке правильности программы введение условий. Теперь последовательность выполняемых Исполнителем команд зависит от состояния этого Исполнителя — какое число находилось на экране Раздвоителя в начале работы, как расставлены стены на поле Робота, какие клетки этого поля закрашены. Простое выполнение программы и получение правильного результата уже не убеждает нас в том, что программа правильная. Мы хотим быть уверенными, что программа будет правильно работать в любой ситуации, а не только в тех, которые мы смогли или захотели проверить. Конечно, лучший способ удостовериться в этом — доказать правильность работы программы. Использование рекурсии лишь усугубляет трудности проверки. Действительно, теперь нам надо не только следить за тем, какая команда выполняется, но и знать, откуда взялась эта команда! Скажем, проверяя выполнение процедуры симметрия из решения задачи 11.1, мы должны помнить, из третьего или из пятого вызова рекурсивной процедуры появилась очередная команда влево и т. д. А если рекурсивных процедур в программе много и они вызывают друг друга? Сложность проверки лишь одна из причин, по которой использования рекурсии лучше избегать. Есть и другие причины: при исполнении на компьютере рекурсивные программы часто работают медленнее и требуют больше памяти, чем нерекурсивные; при замене рекурсивных программ нерекурсивными могут появиться новые красивые идеи, позволяющие взглянуть на задачу с другой стороны. Поэтому, найдя для задачи рекурсивное решение, задумайтесь: нельзя ли обойтись без рекурсии? Задача 11.6 Напишите для Раздвоителя рекурсивную процедуру, которая переводит любое число в нуль за 140 « наименьшее возможное число шагов. Выпишите последовательность команд Раздвоителя при выполнении вашей процедуры с числами: а) 5; б) 9; в) 14. Работая с Роботом, иногда можно избавиться от рекурсии, закрашивая клетки. При этом закрашенные клетки играют роль памяти: проверка условия закрашена позволяет узнать, проходил ли уже Робот по данной клетке. Задача 11.7 Робот стоит сверху от стены на некотором расстоянии от нее. Напишите процедуру, которая доводит Робота до стены и возвращает в исходное положение. а) Разрешается использовать рекурсию. б) Применять раскраску можно, а рекурсию нельзя. Надеемся, что ни одна из этих задач не вызовет у вас затруднения. 4^ Рекурсивный вызов через промежуточную I процедуру Иногда при описании процедуры удобно вызывать ее из самой себя через другую процедуру. Рассмотрим рекурсивное решение задачи о раскраске прямоугольника. Задача 11.8 Решение Робот стоит в левом нижнем углу прямоугольника, огороженного стенами. Внутри прямоугольника стен нет. Составьте программу закраски всех клеток прямоугольника. Напишем программу закраски, использующую две рекурсивные процедуры: ПРОЦ закрась прямоугольник НАЧАЛО ЕСЛИ НЕ закрашена ТО закрась полосу и вернись КОНЕЦ КОНЕЦ е к р и' 141 ПРОЦ закрась полосу и вернись НАЧАЛО ПОКА сверху свободно ДЕЛАТЬ закрась вверх КОНЕЦ ПОКА снизу свободно ДЕЛАТЬ вниз КОНЕЦ ЕСЛИ справа свободно ТО вправо закрась прямоугольник ‘ КОНЕЦ КОНЕЦ Программа состоит из одной команды закрась прямоугольник В нашем решении процедура закрась прямоугольник вызывает процедуру закрась полосу и вернись. Процедура закрась полосу и вернись, в свою очередь, вызывает процедуру закрась прямоугольник. Таким образом, процедура закрась прямоугольник вызывает саму себя через промежуточную процедуру закрась полосу и вернись. А процедура закрась полосу и вернись вызывает саму себя через промежуточную процедуру закрась прямоугольник. В этом случае мы считаем обе процедуры рекурсивными и об-раш;аемся с ними так же, как с обычными процедурами. ИТОГИ в этой главе мы познакомились с очень мощным и важным приемом программирования — рекурсией. Рекурсивный вызов — это вызов процедурой самой себя. Рекурсивный вызов может быть описан непосредственно при описании процедуры или через другие, промежуточные процедуры. При описании рекурсивной процедуры очень важно правильно предусмотреть условие окончания рекурсии, иначе программа может зациклиться. Рекурсией не следует пользоваться при работе с Исполнителями, не имеющими условий. Рекурсия позволяет решать некоторые задачи, не разрешимые никакими другими способами. Однако это сложный способ решения задач, и лучше стремиться обходиться без него. j,:- 1 s 2 H Ц CO задачник - ‘J ^ ^ ‘■■Ж 'UM Справочник по алгоритмическому языку 1. Значение истинности простых и сложных условий Возможных значений два: ИСТИНА и ЛОЖЬ. Сложные условия составляются из простых с помощью логических операций И, ИЛИ, НЕ. Значения истинности сложных условий вычисляются по правилам: ИСТИНА И ИСТИНА = ИСТИНА ИСТИНА И ЛОЖЬ = ЛОЖЬ ЛОЖЬ и ИСТИНА = ЛОЖЬ ложь и ложь = ложь ИСТИНА или ИСТИНА = ИСТИНА ИСТИНА ИЛИ ложь = ИСТИНА ЛОЖЬ или ИСТИНА = ИСТИНА ЛОЖЬ или ложь = ложь НЕ ИСТИНА = ЛОЖЬ НЕ ЛОЖЬ = ИСТИНА 2. Конструкции 2.1. Конструкция процедуры , ПРОЦ <имя процедуры> ' НАЧАЛО I <программа, описывающая, что делает процедура> КОНЕЦ 2.2. Конструкция простого цикла ПОВТОРИТЬ <число> РАЗ <группа команд Исполнителя> КОНЕЦ 144 ЗАДАЧНИК 2.3. Конструкция ветвления Первая форма: ЕСЛИ <условие> ТО <группа команд Исполнителя> КОНЕЦ Вторая форма: ЕСЛИ <условие> ТО ' <первая группа команд Исполнителя> 1 ИНАЧЕ ' <вторая группа команд Исполнителя> I КОНЕЦ ' 2.4. Конструкция повторения ПОКА <условие> ДЕЛАТЬ ' <группа команд Исполнителя> КОНЕЦ I 3.1 Среда, системы команд и условия ' Исполнителей 3.1. Крестьянин (глава 1, п. 1) Среда Крестьянина представляет собой два берега реки. На каждом берегу могут оказаться сам Крестьянин (с лодкой), волк, коза и капуста. При этом каждый из объектов находится на одном из берегов и исчезнуть не может. Невозможная ситуация (ОТКАЗ) возникает, когда на одном из берегов оказываются волк с козой или коза с капустой в отсутствие Крестьянина. Система команд Крестьянина состоит из четырех команд: перевези волка перевези козу перевези капусту переправься ти ч е с к о м у языку 145 По каждой из команд перевези Крестьянин перевозит указанный объект. ОТКАЗ возникает, если такого объекта нет на берегу Крестьянина. Команда переправься заставляет одного Крестьянина переправиться в лодке, не беря ничего с собой. Условия отсутствуют. 3.2. Водолей (глава 1, п. 3) Исполнитель Водолей — не один Исполнитель, а целое семейство Исполнителей. Конкретный Исполнитель определяется выбранной средой — количеством емкостей и их объемами. Среда Водолея задается количеством емкостей и их объемами. Как правило. Водолей работает с двумя или тремя емкостями, обозначаемыми латинскими буквами А, В и С. Объемы емкостей — положительные целые числа. Система команд. У Водолея три типа команд: наполни А вылей из А перелей из А в В Вместо указанной в команде емкости могут стоять другие емкости. По команде наполни Водолей наполняет указанный сосуд до краев. По команде вылей Водолей опустошает указанный сосуд. По команде перелей Водолей переливает из первого сосуда во второй столько жидкости, сколько помещается во втором сосуде. Непоместившаяся жидкость остается в первом сосуде. Условия отсутствуют. 3.3. Удвоитель (глава 1, п. 4) Среда Удвоителя — экран, на котором написано целое неотрицательное число. Система команд. У Удвоителя две команды. Команда прибавь 1 вызывает прибавление единицы к числу на экране. Команда умножь на 2 вызывает умножение числа на экране на 2. Условия отсутствуют. 146 ЗАДАЧНИК 3.4. Раздвоитель (глава 3, п. 8) Среда у Раздвоителя такая же, как у Удвоителя, — экран, на котором написано целое неотрицательное число. Система команд. У Раздвоителя две команды. По команде вычти 1 Раздвоитель уменьшает число на экране на единицу. Если число на экране — нуль, то возникает ОТКАЗ. По команде раздели на 2 Раздвоитель делит число на экране пополам. Если число на экране было нечетным, то возникает ОТКАЗ. Условия. У Раздвоителя два условия. Условие положительное истинно, если число на экране положительное (не нуль). Условие четное истинно, если число на экране четное. 3.5. Кузнечик (глава 1, п. 5) Как и Водолей, Кузнечик — не один Исполнитель, а целое семейство Исполнителей. Каждого конкретного Кузнечика можно получить, указав, какие прыжки (вперед и назад) и на какое расстояние он может делать. Среда Кузнечика — множество целых точек на прямой. В каждый момент времени Кузнечик находится в одной из этих точек. В задачнике предполагается, что каждая из точек, изображающих целое число, покрашена в черный или белый цвет. Обычно все точки белые. Система команд Кузнечика зависит от того, какого именно Кузнечика мы хотим получить, в книге для ученика используются Кузнечики с системами команд вперед 3 . вперед 7 и ' назад 2 назад 5 По команде вперед <число> Кузнечик перемещается вправо на указанное число единиц. По команде назад <число> Кузнечик перемещается на заданное число единиц влево. В задачнике к системе команд Кузнечика добавляется команда перекрась. По этой команде Кузнечик перекрашивает клетку, на которой он находится, в противоположный цвет. Условия отсутствуют. Справочник по алгоритмическому языку 147 3.6. Лодка (глава 3, п. 1) Среда этого Исполнителя — два берега реки, на каждом из которых могут находиться несколько солдат, один или два мальчика и лодка. Система команд. Имеется три команды; солдат мальчик два мальчика При выполнении каждой из этих команд соответствующий персонаж (персонажи) переправляется в лодке на другой берег. ОТКАЗ возникает, когда на том берегу, где находится лодка, нет соответствующего персонажа (солдата, мальчика или двух мальчиков). Условия отсутствуют. 3.7. Рабат (глава 5) Среда Робота задается в виде поля, разбитого на квадратные клетки. Между клетками можно установить стены (сделать лабиринт). Некоторые клетки могут быть закрашены. Робот находится в любой момент на одной из клеток поля. Система команд. У Робота четыре команды движения: вверх вправо вниз влево При выполнении этих команд Робот передвигается соответственно на одну клетку вверх, вниз, вправо или влево. Если на пути Робота расположена стена, то возникает ОТКАЗ. Команда закрась заставляет Робота закрасить клетку, на которой он находится. Если клетка уже была закрашена, то Робот просто ничего не делает. ОТКАЗ при этом не возникает. Условия сверху свободно снизу свободно справа свободно слева свободно истинны, если в соответствующем направлении нет стены. В таком случае Робот может сделать шаг в этом направлении, не опасаясь возникновения ОТКАЗа 148 ЗАДАЧ > I Условие закрашена истинно, если клетка, на которой стоит Робот, закрашена. 3.8. Чертежник (глава 6) Среда. Чертежник живет на координатной плоскости. У него имеется перо, которое в каждый момент находится в одной из точек плоскости. Перо либо поднято (над плоскостью), либо опущено (расположено на плоскости). Система команд. У Чертежника две команды движения: переведи в точку (<число>, <число>) сдвинь на вектор (<число>, <число>) Первая команда переводит перо Чертежника в точку с указанными координатами. Вторая сдвигает его из точки, в которой оно находилось, на вектор с указанными компонентами. Опущенное перо оставляет след — отрезок, соединяющий его начальное и конечное положения. Поднятое перо следа не оставляет. Две команды управления пером подними перо опусти перо переводят его в указанное положение. Если перо уже было в этом положении, то ничего не происходит. Условия отсутствуют. 3.9. Черепаха (глава 7) Среда. Черепаха живет на (бескоординатной) плоскости. У нее есть направление, в котором она смотрит. Черепаха оставляет след или не оставляет след в зависимости от того, опущен или поднят ее хвост. Система команд. У Черепахи есть две команды движения. Обе они имеют параметр: вперед (<число>) назад (<число>) му языку 149 По команде вперед (назад) Черепаха движется в том направлении, в котором она смотрит (в противоположном направлении). Расстояние, на которое она перемещается, задается числом. Черепаха с опущенным хвостом оставляет след, с поднятым не оставляет. По командам вправо (<число>) влево (<число>) Черепаха поворачивается вправо (влево) на указанное число градусов, оставаясь при этом на месте. По командам подними хвост опусти хвост она переводит хвост в поднятое (опущенное) положение. Ленивая Черепаха — вариант Черепахи. Это Исполнитель, стоящий на месте. Ленивая Черепаха только поворачивается, исполняя команды вправо и влево. Все остальные команды она просто игнорирует. Условия отсутствуют. 3.10. Ханойская башня (глава 8) Ханойская башня — семейство Исполнителей, с чем мы уже встречались ранее. Каждый конкретный Исполнитель задается числом кружков, размещаемых на трех стержнях А, В и С. В задачнике встречаются и другие Исполнители, связанные с Ханойской башней. Они подробно описаны в соответствующих задачах. Среда. Все кружки разного размера, и на каждом стержне самый большой кружок размещается внизу, затем кружок поменьше, далее еще меньше, и, наконец, вверху находится самый маленький кружок. Система команд. У Ханойской башни шесть команд с параметром: перенеси с А на В (<номер кружка>) перенеси с А на С (<номер кружка>) перенеси с В на А (<номер кружка>) перенеси с В на С (<номер кружка>) 150 ЗАДАЧНИК перенеси с С на А (<номер кружка>) перенеси с С на В (<номер кружка>) По такой команде кружок с указанным номером перемещается с первого указанного поля на второе указанное поле. Например, команда перенеси с А на В (3) вызывает перемещение третьего кружка с поля А на поле В. ОТКАЗ может возникнуть, если: ' верхний кружок на первом поле имеет не тот номер, который указан в команде; • после перемещения кружка на новое поле он оказывается не самым маленьким на этом поле. Условия отсутствуют. 3.11. Директор строительства (глава 10) Директор строительства отличается от остальных Исполнителей тем, что фактически это не один, а несколько Исполнителей, называемых бригадами. Каждая бригада получает свою программу работы и действует в соответствии с этой программой. Среда Директора строительства определяется проектом, который необходимо запрограммировать. Проект представляет собой набор неперекрывающихся геометрических фигур на вертикальной плоскости. Фигуры перенумерованы (произвольно выбранными номерами) и «опираются» друг на друга. Они называются блоками. Каждый блок должен опираться на другой блок или на горизонтальную плоскость (землю, основание). В ряде задач земля является неровной (негоризонтальной). Система команд. У Директора одна команда с параметрами: установи (<номер блока>) По этой команде бригада устанавливает блок с указанным номером. ОТКАЗ возникает, если не установлен какой-либо блок, на который указанный в команде блок опирается, или если блока с таким номером нет среди установленных блоков. Условия отсутствуют. { fct dm j Задачи без условий IJ Водолей Если в условии задачи не указано начальное количество воды в сосудах, то это означает, что все сосуды пусты. 1.1. Напишите количество воды в каждом сосуде после выполнения каждой команды следующей программы: 1.2. Команда А (4 л) В (11 л) 0 0 наполни А перелей из А в В наполни А перелей из А в В наполни А перелей из А в В наполни А перелей из А в В Ниже приведены состояния сосудов А и В после выполнения Водолеем некоторой программы: Команда А (4 л) В (7 л) 0 0 0 7 4 3 0 3 3 0 3 7 4 6 0 6 4 2 152 ЗАДАЧНИК Восстановите команды в этой программе. Попробуйте дописать программу так, чтобы в одном из сосудов остался 1 литр. 1.3. Восстановите недостающие команды и количество воды в сосудах в новой программе: Команда А (7 л) В (17 л) 2 17 0 12 перелей из В в А вылей из А 5 17 перелей из В в А 7 8 0 1 Следующий цикл задач предназначен для решения сложной задачи: Пусть у нас имеются два сосуда А и В. Вначале оба сосуда пусты. Можно ли написать такую программу, чтобы в результате ее выполнения в одном из сосудов оказался 1 литр воды? Конечно, эта программа зависит от объемов со- - ” " п судов. Например, если объем сосуда А равен 1 лит- наполни А [ РУ, то программа будет выглядеть совсем просто: 1.4. Пусть объем сосуда А равен 3 литрам, а объем сосуда В — 2 литрам, а) Напишите программу из двух команд, в результате выполнения которой в сосуде А окажется 1 литр воды, б) Для сосудов каких других объемов годится та же программа? в) Напишите программу, в результате выполнения которой в сосуде В окажется 1 литр воды. 1.5. Водолей взял 9-литровый и 2-литровый сосуды. Напишите программу, выполняя которую Водолей отмерит 1 литр. 1.6. Водолей взял 5-литровый и 3-литровый сосуды. Напишите программу, выполняя которую Водолей отмерит 1 литр. Постарайтесь придумать самую короткую программу. Задачи без условий 153 1.8. 1.9. 1.7. Водолей взял 7-литровый и 5-литровый сосуды. Напишите программу, выполняя которую Водолей отмерит 1 литр. Постарайтесь придумать самую короткую программу. Водолей взял 6-литровый и 4-литровый сосуды. Может ли Водолей отмерить 1 литр? Обоснуйте свой ответ. Водолей взял 2-литровый сосуд А. Какой объем может иметь сосуд В, чтобы Водолей мог отмерить 1 литр воды? Как описать все возможные значения этого объема? Обоснуйте свой ответ. 1.10. Водолей взял 4-литровый сосуд А. Какой объем может иметь сосуд В, чтобы Водолей мог отмерить 1 литр воды? Как описать все возможные значения этого объема? Обоснуйте свой ответ. 1.11. Объем сосуда А равен 6 литрам, а объем сосуда В равен 9 литрам. Сможет ли Водолей отмерить 1 литр? 1.12. Водолей взял 3-литровый сосуд А. Какой объем может иметь сосуд В, чтобы Водолей мог отмерить 1 литр воды? Как описать все возможные значения этого объема? Обоснуйте свой ответ. 1.13. Водолей взял 6-литровый сосуд А. Какой объем может иметь сосуд В, чтобы Водолей мог отмерить 1 литр воды? Как описать все возможные значения этого объема? Обоснуйте свой ответ. Итак, если объемы сосудов А и В имеют общий делитель, больший, чем единица, то отмерить 1 литр с их помощью невозможно. 1.14. Докажите, что последний вывод верен. Мы еще не в состоянии сказать, можно ли отмерить 1 литр, если объемы сосудов взаимно просты (не имеют общих делителей, больших единицы). Пока это получалось во всех задачах, но мы не знаем, будет ли так всегда. Задачи на эту тему собраны в части В задачника. А сейчас мы перейдем к другим задачам. 1.15. Сосуд А имеет объем 16 литров, а сосуд В — 5 литров. Как отмерить: а) 9 литров; б) 8 литров? 1.16. У Водолея есть 3 сосуда вместимостью б, 12 и 15 литров. Может ли он отмерить 1 литр? 2 литра? 3 литра? 1.17. У Водолея есть 3 сосуда вместимостью 6, 10 и 15 литров. Может ли он отмерить: а) 1 литр; б) 7 литров? Если да, то напишите соответствующие программы. 1.18. У Водолея есть 6-литровый сосуд А, в котором налито 4 литра молока, пустой сосуд В вместимостью 1 литр и 6-литровый сосуд С с 4 литрами воды. Водолей выполнил программу (см. справа). Он сделал это так быстро, что никто даже не заметил, успело ли равномерно перемешаться молоко в воде или нет после второй команды, Чего больше — молока в воде или воды в молоке? Ответ обоснуйте. перелей из А в В перелей из В в С перелей из С в В перелей из В в А 154 ЗАДАЧНИК 1.19. В программе для Водолея идут подряд две строки перелей из А в В перелей из В в А Петя решил упростить программу и выбросил эти две строки. Вася объяснил Пете, что новая программа работает не так, как работала исходная. Приведите пример такой про- граммы, указав величины емкостей стоянии обе емкости пустые. 1.20. У Водолея есть три сосуда А, В и С, в каждый из которых налито какое-то количество воды. Верно ли, что после выполнения указанной справа программы количество воды в каждом из сосудов окажется тем же самым? Ответ обоснуйте. А и В. В начальном со- перелей из А в В перелей из В в С перелей из С в А 2. Удвоитель умножь на 2 умножь на 2 прибавь 1 умножь на 2 умножь на 2 умножь на 2 прибавь 1 умножь на 2 2.1. Перед началом работы программы на экране Удвоителя горело число 1. Удво- а) итель выполнил программу а. а) Какое число загорелось на экране Удвоителя после выполнения этой программы? б) Сколько команд выполнил Удвоитель? 2.2. Перед началом работы программы на экране Удвоителя горело число 5. Удво- б) итель выполнил программу б. Какое число загорелось на экране Удвоителя после выполнения этой программы? Какие числа загорались на экране Удвоителя после каждой команды? 2.3. Выполняя только команду прибавь 1, Удвоитель из числа О получил число 13. Сколько команд выполнил Удвоитель? 2.4. Выполняя только команду прибавь 1, Удвоитель из числа 27 получил число 293. Сколько команд выполнил Удвоитель? 2.5. Может ли Удвоитель из числа 33 получить число 19? 2.6. Докажите, что Удвоитель может из любого числа получить любое большее число. 2.7. Перед началом работы программы на экране Удвоителя горит число 1. Удвоитель 10 раз выполнил команду умножь на 2. Выпишите подряд состояния Удвоителя после каждой команды. дачи без условий 155 Какое число будет гореть на экране после окончания работы программы? 2.8. Выполняя только команду умножь на 2, Удвоитель из числа 2 получил число 512. Сколько команд выполнил Удвоитель? 2.9. Выполняя только команду умножь на 2, Удвоитель из числа 12 получил число 192, Сколько команд выполнил Удвоитель? 2.10. Может ли Удвоитель из числа 15 получить число 280, выполняя только команды умножь на 2? 2.11. Желая из числа 1 получить число 8, Петя написал программу а. Напишите более короткую программу, дающую тот же результат. а) умножь на 2 ‘ прибавь 1 ' прибавь 1 ! умножь на 2 б) умножь на ' умножь на умножь на ' прибавь 1 прибавь 1 прибавь 1 * прибавь 1 2 ‘ в) ' умножь на 2 2 ' прибавь 1 2 * ' прибавь 1 умножь на 2 прибавь 1 умножь на 2 прибавь 1 , . прибавь 1 умножь на 2 прибавь 1 2.12. Чтобы из числа 1 получить число 12, написали программу б. Напишите более короткую программу, дающую тот же результат. Какая команда в вашей программе последняя? 2.13. Чтобы из числа 5 получить число 105, Оля написала программу в. Верно ли, что Олина программа самая короткая? Если нет, то напишите более короткую программу, дающую тот же результат. Какая команда в вашей программе последняя? 2.14. На экране написано число 8. Число 18 из 8 можно получить за 3 команды так (см. справа). Но можно получить и быстрее. Напишите более короткую программу. умножь на 2 прибавь 1 прибавь 1 Рассмотрим Исполнителя Квадратор с двумя командами, который по команде прибавь 1 увеличивает число на экране на 1, а по команде возведи в квадрат возводит его в квадрат. 2.15. Напишите программы получения Квадратором из числа 1 чисел: а) 5; б) 12; в) 35; г) 100. Постарайтесь, чтобы Квадратор совершал как можно меньше операций. 156 задачи;^! 2.16. Напишите программы получения Квадратором: а) из числа 2 числа 17; б) из числа 3 числа 83; в) из числа 4 числа 36. Постарайтесь, чтобы Квадратор совершал как можно меньше операций. 3. Кузнечик в задачах 3.1—3.20 рассматривается Кузнечик с командами вперед 3, назад 2. 3.1. Нарисуйте стрелками перемещения Кузнечика, выполнившего программу, указанную справа (начальное положение Кузнечика любое). 3.2. На рисунке 3.1 стрелками показано, как перемещался Кузнечик, выполняя некоторую программу. Восстановите эту программу. вперед 3 назад 2 вперед 3 вперед 3 назад 2 назад 2 -□-CHIhQC] ODO Рис. 3.1 3.3. к Пятой командой программы из пяти команд, которую выполнил Кузнечик, была команда назад 2, На рисунке 3.2 стрелками показано, как Кузнечик выполнял команды 1 и 3 и где он оказался после выполнения программы. Восстановите эту программу. Рис. 3.2 К 3.4. Кузнечик выполнил программу (см. справа). На рисунке 3.3 стрелки, указывающие, как Кузнечик выполнял команды, стерлись. К сожалению, стерлась и третья команда программы. Какая это команда? Г вперед 3~| I назад 2 I ^ назад 2 I I вперед 3 I оосш Рис. 3.3 Здесь Кузнечик начал выполнять программу Здесь Кузнечик закончил выполнять программу А Задач, ьез условий 157 3.5. Из программы, которую выполнил Кузнечик (см. справа), пропали две команды. Известны также начальное и конечное положения Кузнечика (рис. 3.4). Восстановите эти команды. вперед 3 назад 2 вперед 3 Рис. 3.4 К Здесь Кузнечик начал выполнять программу Здесь Кузнечик закончил выполнять программу 3.6. Напишите программу из трех команд, переводяш;ую Кузнечика с квадратика О на квадратик 4. 3.7. Напишите программу из трех команд, переводящую Кузнечика с квадратика О на квадратик -1. 3.8. Переведите Кузнечика четырьмя командами с квадратика О на квадратик -3. 3.9. Переведите Кузнечика четырьмя командами с квадратика О на квадратик 7. 3.10. Напишите три разные программы из трех команд каждая, переводящие Кузнечика с квадратика 0 на квадратик -1. 3.11. Напишите три разные программы из трех команд каждая, переводящие Кузнечика с квадратика 0 на квадратик 4. 3.12. Кузнечик с квадратика 0 попал на квадратик 7 за четыре прыжка, а) Сколько различных программ могут это сделать? Выпишите их. б) Сколько среди них программ, при выполнении которых Кузнечик не попадает на квадратики с отрицательными номерами? Стартовав с квадратика 0, Кузнечик выполнил программу (см. справа). , ” t [ впеоел 3 ч Выпишите последовательность номеров квадратиков, на которых побывал Кузнечик. Стартовав с квадратика 0 и выполнив некоторую программу. Кузнечик побывал последовательно на квадратиках с номерами 0, 3, 1, 4, 2, о, -2. а) Выпишите последовательность номеров квадратиков, на которых побывает Кузнечик, выполняя эту же программу, если начальное положение Кузнечика — квадратик 5. б) Восстановите всю программу. 3.15. Выполнив некоторую программу. Кузнечик с квадратика -2 попал на квадратик 6. На какой квадратик попадет Кузнечик, выполнив ту же программу, начиная с квадратика 1? 3.13. 3.14. назад 2 вперед 3 вперед 3 вперед 3 назад 2 назад 2 назад 2 158 ЗАДАЧНИК 3.16. Кузнечик выполнил пять команд программы и оказался на том же месте, откуда начал движение, а) Напишите такую программу, б) Сколько различных программ с таким свойством существует? 3.17. Кузнечик выполнил программу и оказался на том же квадратике, с которого он начал. Оказалось, что команд назад 2 в программе на 10 больше, чем команд вперед 3. Сколько всего команд в программе? 3.18. Кузнечик выполнил программу, в которой команд назад 2 на 13 больше, чем команд вперед 3. Всего в программе 27 команд. На сколько квадратиков сместился Кузнечик и в какую сторону? 3.19. Кузнечик выполнил некоторую программу и оказался на 3 квадратика левее того места, с которого он начал. Всего в программе 13 команд. Может ли такое быть? 3.20. Кузнечик выполнил некоторую программу и оказался на 6 квадратиков правее того места, с которого он начал. Всего в программе 17 команд. Сколько в программе команд вперед 3 и команд назад 2? Начиная с этого момента к командам Кузнечика добавляется команда перекрась. 3.21. Начальное положение Кузнечика — квадратик 0. В чем различие между результатами выполнения следующих программ? 1-я программа вперед 3 I перекрась 2-я программа Г перекрась | I вперед 3 J 3.22. 3.23. Кузнечик стартовал с квадратика -1 и выполнил программу а. Какие квадратики он закрасил? Начальное положение Кузнечика — квадратик 0. Вставьте в программу б Кузнечика команды перекрась так, чтобы после выполнения новой программы оказались закрашенными квадратики 0, 3 и 5. Проверьте свое решение рисунком. а) It вперед 3 б) перекрась вперед 3 назад 2 перекрась назад 2 J вперед 3 назад 2 вперед 3 назад 2 вперед 3 I 3.24. В каждой из следующих программ начальное положение Кузнечика — квадратик 0. Нарисуйте результаты их выполнения. А. Задач : ьез условий 159 а) вперед 3 перекрась назад 2 перекрась назад 2 перекрась ”1 ) I б) назад 2 перекрась вперед 3 перекрась назад 2 перекрась в) назад 2 перекрась назад 2 перекрась вперед 3 перекрась Отметьте конечное положение Кузнечика. 3.25. Впишите пропущенные команды так, чтобы Кузнечик, начав с квадратика О, закончил выполнение каждой программы (программы а и б) на квадратике 7. а)( вперед 3 вперед 3 вперед 3 б). вперед 3 назад 2 I вперед 3 t , вперед 3 в), перекрась вперед 3 3.26. Кузнечик выполнил программу (программа в) и с квадратика О попал на квадратик 6, перекрасив несколько квадратиков. Восстановите две пропущенные команды. 3.27. В каждой из следующих программ начальное положение Кузнечика — квадратик -2. Нарисуйте результаты выполнения программ. Отметьте конечное положение Кузнечика. а) вперед 3 J перекрась 1^ назад 2 Г перекрась I вперед 3 I перекрась f I б) назад 2 перекрась перекрась вперед 3 перекрась назад 2 перекрась вперед 3 перекрась назад 2 3.28. Начальное положение Кузнечика — квадратик 0. Перед выполнением программы все квадратики на прямой были белыми. Результат выполнения некоторой программы показан на рисунке 3.5. Какие квадратики закрасит Кузнечик, стартовав с квадратика 3 и выполнив ту же программу? Рис. 3.5 -5 -4 -3 -2 -1 о 1 2 3 4 5 6 7 160 ЗАДАЧНИК 3.29. До начала работы программы все квадратики на прямой были белыми, а результат ее выполнения показан на рисунке 3.6. В программе 6 команд. Каковы начальное и конечное положения Кузнечика? Восстановите программу. Рис. 3.6 а-ач1шч^-ш1к>п-сьс>оо- _5 _4 _3 _2 -1 О 1 2 3 4 5 6 7 3.30. 3.31. Начальное положение Кузнечика — квадратик 0. Перед выполнением программы (см. справа) все квадратики на прямой были белыми. Выпишите, на каких квадратиках Кузнечик побывал: а) один раз; б) два раза; в) три раза; г) какие квадратики окажутся закрашенны- ___________^ ми, если вставить команду перекрась после ‘ каждой команды программы (начиная с первой)? На каких квадратиках побывает Кузнечик, стартовав с квадратика О и выполнив следующую программу: ПОВТОРИТЬ 17 РАЗ вперед 3 назад 2 КОНЕЦ LHa КОНЕЦ вперед 3 назад 2 вперед 3 назад 2 вперед 3 назад 2 назад 2 назад 2 вперед 3 вперед 3 I назад 2 3.32. Улитка проползает за день 3 метра вверх, а за ночь спускается на 2 метра вниз. Когда она достигнет вершины 10-метрового дерева, утром отправившись в путешествие от его корней? 3.33. В следующих двух задачах Кузнечик начинает выполнять программы с квадратика О, и все квадратики белые. Какие квадратики будут закрашены в результате выполнения программ. Проверьте свои решения рисунками. а) ПОВТОРИТЬ 5 РАЗ перекрась вперед 3 назад 2 КОНЕЦ I б)) ПОВТОРИТЬ 5 РАЗ I I вперед 3 1 назад 2 I перекрась КОНЕЦ 3.34. Как нужно изменить программу а из предыдущей задачи, чтобы в результате ее выполнения Кузнечик закрашивал квадратики с нулевого по пятый включительно? "1 д )ез условии 161 3.35. Кузнечик стоит на квадратике 4. Он должен попасть на квадратик с номером 17 и перекрасить все квадратики с 4-го по 17-й. Напишите такую программу. 3.36. Кузнечик стоит на квадратике 13. Он должен попасть на квадратик с номером 5 и перекрасить все квадратики с 5-го по 13-й. Напишите такую программу. 3.37. Кузнечик стоит на нулевом квадратике, и все квадратики белые. Он выполнил программу, а) На каких квадратиках Кузнечик побывал? б) Какие квадратики он закрасил? Проверьте свое решение рисунком. 3.38. Кузнечик выполнил программу. Сколько раз Кузнечик выполнил команду: а) назад 2; б) вперед 3; в) перекрась; г) сколько и какие квадратики оказались закрашенными после выполнения этой программы, если Кузнечик начал выполнять ее с квадратика О и перед началом работы все квадратики были белыми? Измените эту программу так, чтобы Кузнечик выполнял те же действия в том же порядке, но чтобы в новой программе: д) был всего один цикл; е) не было цикла ПОВТОРИТЬ 2 РАЗ. 3.39. Кузнечик выполнил программу, а) Чем текст этой программы отличается от текста программы из предыдуш;ей задачи? Сколько раз Кузнечик выполнил команду: б) назад 2; в) вперед 3; г) перекрась; д) сколько и какие квадратики оказались закрашенными после выполнения этой программы, если Кузнечик начал выполнять ее с квадратика О и перед началом работы все квадратики были белыми? Измените эту программу так, чтобы Кузнечик выполнял те же действия в том же порядке, но чтобы в новой программе: е) был всего один цикл; ж) не было цикла ПОВТОРИТЬ 3 РАЗ. назад 2 ПОВТОРИТЬ 6 РАЗ вперед 3 назад 2 перекрась назад 2 вперед 3 КОНЕЦ ПОВТОРИТЬ 2 РАЗ назад 2 перекрась ПОВТОРИТЬ 3 РАЗ вперед 3 перекрась КОНЕЦ перекрась КОНЕЦ ПОВТОРИТЬ 3 РАЗ назад 2 перекрась ПОВТОРИТЬ 2 вперед 3 перекрась КОНЕЦ перекрась КОНЕЦ РАЗ 162 ЗАДАЧНИК 3.40. Оля написала для Кузнечика процедуру шаг вперед. А Саша написал процедуру шаг вперед и крась: ПРОЦ шаг вперед НАЧАЛО вперед 3 назад 2 КОНЕЦ ПРОЦ шаг вперед и крась ' НАЧАЛО вперед 3 назад 2 перекрась 'I КОНЕЦ Напишите программу, использующую эти процедуры, при выполнении которой Кузнечик закрасит квадратики, как это показано на рисунке 3.7 (первоначально Кузнечик стоял на квадратике 0, и все квадратики были белыми). ОООСЩОО... ооооосю- о 1 2 3 4 5 6 48 49 50 51 52 53 54 Рис. 3.7 3.41. В этой задаче Кузнечик может выполнять только команду вперед 2. Сколько прыжков совершил Кузнечик, попав: а) с квадратика 8 на квадратик 22; б) с квадратика -1995 на квадратик 1995; в) на какой квадратик попал Кузнечик с квадратика -7, если он совершил 9 прыжков; г) с какого квадратика начинал свои прыжки Кузнечик, если за 24 прыжка он попал на квадратик 137; д) может ли Кузнечик, выполняя только команду вперед 2, попасть с квадратика 123 на квадратик 276? на квадратик 351? на квадратик 335? Дальше будем рассматривать Кузнечика с двумя командами вперед 2 и назад 2 3.42. Может ли такой Кузнечик попасть с квадратика 0 на квадратик 1? Вы, вероятно, уже поняли, что с квадратика 0 удается допрыгать не до всех квадратиков. Номера тех из них, до которых Кузнечик может допрыгать, называются четными. Напишем над этими квадратиками число 0. До остальных квадратиков Кузнечик сможет допрыгать, стартовав с квадратика 1. Их номера называются нечетными. Напишем над этими квадратиками число 1. Число, написанное над каждым квадратиком, называется остатком от деления номера этого квадратика на 2. А. Задачи без условий 163 3.43. Выпишите остатки от деления на 2 первых двадцати: а) положительных чисел; б) отрицательных чисел. 3.44. Может ли Кузнечик, выполняя только команды вперед 2 и назад 2, попасть с четного квадратика на нечетный? с нечетного квадратика на нечетный? с нечетного на четный? с четного на четный? 3.45. В этой задаче Кузнечик может выполнять только команду вперед 3. Сколько прыжков совершил Кузнечик, попав: а) с квадратика О на квадратик 21; б) с квадратика 21 на квадратик 1995; в) с квадратика 2 на квадратик 77? На какой квадратик попал Кузнечик: г) с квадратика 5, если он совершил 7 прыжков; д) с квадратика -17, если он совершил 173 прыжка; е) с квадратика -317, если он совершил 28 прыжков; ж) с какого квадратика начинал свои прыжки Кузнечик, если за 43 прыжка он попал на квадратик 37? Может ли Кузнечик, выполняя только команду вперед 3, попасть: з) с квадратика О на квадратик 176; на квадратик 351; на квадратик 136; и) с квадратика 1 на квадратик 176; на квадратик 351; на квадратик 136; к) с квадратика 2 на квадратик 176; на квадратик 351; на квадратик 136; л) с квадратика -17 на квадратик 176; на квадратик 351; на квадратик 136? Дальше будем рассматривать Кузнечика с двумя командами вперед 3 и назад 3 3.46. Может ли такой Кузнечик допрыгать с квадратика О до квадратика 1? до квадратика 2? И этому Кузнечику с квадратика О не удается допрыгать до всех квадратиков. Напишем над квадратиками, до которых он сможет допрыгать с квадратика О, число 0. Над квадратиками, до которых Кузнечик допрыгает с квадратика 1, напишем число 1. А над квадратиками, которых он достигнет, начав с квадратика 2, напишем число 2. Над каждым квадратиком будет написано одно из чисел 0, 1 или 2. Это число называется остатком от деления номера квадратика на 3. 3.47. Выпишите остатки от деления на 3 первых двадцати: а) положительных чисел; б) отрицательных чисел. 3.48. Какие числа написаны над квадратиками с номерами 201? 1952? -1995? 1 000 000? -1 000 000? 3.49. Может ли Кузнечик допрыгать с нулевого квадратика до квадратика, над которым написана цифра 2, цифра 1, выполняя только команды вперед 3 и назад 3? 164 J hi 3.50. Кузнечик может выполнять команды вперед 7 и назад 3. а) Может ли Кузнечик допрыгать с квадратика О до квадратика 1? 2? 3? 4? 5? 6? -1? -2? Напишите программы там, где это возможно, б) Может ли Кузнечик с любого квадратика допрыгать до любого? в) Напишите программу, выполняя которую Кузнечик закрасит все квадратики с нулевого до 100-го. Подумайте, какую процедуру здесь было бы удобно применить, и напишите ее. г) Можно ли решить задачу пункта в так, чтобы Кузнечик побывал на каждом квадратике с нулевого до 100-го по одному разу? Обоснуйте свой ответ. 3.51. В этой задаче Кузнечик может выполнять только команды вперед 15 и назад 6. а) Может ли Кузнечик допрыгать с квадратика О до квадратика 24? 3? 20? 1? Напишите соответствующие программы там, где это возможно, б) Может ли Кузнечик с любого квадратика допрыгать до любого? в) До каких квадратиков может допрыгать этот Кузнечик с квадратика О? 3.52. У Кузнечика есть две команды вперед 7 и назад 5. Пусть а — целое положительное число. Может ли Кузнечик, не попадая на квадратики с отрицательными номерами, попасть: а) с квадратика О на квадратик а; б) с квадратика а на квадратик О? 3.53. У Кузнечика есть команда вперед m и команда назад п (т и п — положительные целые числа). Известно, что Кузнечик может попасть с квадратика 4 на квадратик 6. а) Существует ли программа, переводящая Кузнечика с квадратика 6 на квадратик 4? б) Существуют ли программы, переводящие Кузнечика с квадратика 4 на квадратик бис квадратика 6 на квадратик 4 так, что он не попадает на квадратики с отрицательными номерами? 3.54. Имеется п кубиков высотой 2 и m кубиков высотой 3. При каких значениях тип можно построить две башни одинаковой высоты, использовав при этом все m -Ь п кубиков? 3.55. Кузнечик сделал несколько прыжков вперед, затем несколько прыжков назад и вернулся в исходную точку 0. Напишите программу для: а) Кузнечика (3, 2); б) Кузнечика (7, 5); в) Кузнечика (4, 6). 3.56. а) Напишите программу, которая переводит Кузнечика с командами вперед 3, назад 2 из квадратика О в квадратик 18 так, что Кузнечик не попадает в квадратики 3, 6, 9, 12, 15. б) Есть ли такая же программа для Кузнечика с командами вперед 2, назад 3? Ответ обоснуйте. 3.57. Докажите, что, стартовав с квадратика О, Кузнечик с командами вперед 2, вперед 3 может допрыгать до квадратика с любым положительным номером, начиная с 2, а до квадратика с номером 1 допрыгать не может. 165 3.58. Найдите, до каких квадратиков может, а до каких не может допрыгать Кузнечик с командами: а) вперед 3, вперед 4; б) вперед 2, вперед 5; в) вперед 3, вперед 5. 4. Переправа 4.1. К реке подошли шестьдесят солдат. Им нужно переправиться через реку. Рядом с берегом на лодке катаются четыре девочки. Лодка может выдержать не более двух солдат. Течение настолько сильное, что переправиться через реку девочки могут не по одной, а только вдвоем. Как солдатам переправиться через реку и вернуть лодку девочкам? Придумайте команды Исполнителя и программу, выполнив которую ваш Исполнитель решит эту задачу. 5. Робот 5,1. 5.2. Вот программа для Робота (команды в ней пронумерованы): 1. Нарисуйте в тетради клетчатое поле Робо- 2. та. Выбрав произвольное начальное положе- 3. ние Робота, поставьте на клеточке, где он 4. оказался после выполнения первой команды, 5. число 1, после второй команды — число 2 6. и т. д. Вот как ходил Робот, выполняя новую программу (рис. 5.1). 8 10 11 7 12 6 14 13 5 15 16 17 18 5.3. Рис. 5.1 Первой командой в программе была команда влево. Напишите, какую программу выполнял Робот. Робот выполнил программу (см. справа). Нарисуйте в тетради клетчатое поле Робота и закрасьте клетки в соответствии с этой программой. вправо вниз вниз вправо вниз влево закрась вправо вправо закрась вправо вправо закрась вверх влево закрась влево влево влево закрась 166 ЗАД/ 9 2 3 4 5.4. На рисунке 5.2 показано начальное положение Робота. Отмечены клетки, которые должны быть закрашены после выполнения программы. Рис. 5.2 Напишите программу, выполняя которую Робот закрасит указанные клетки. 5.5. Напишите программы, в результате выполнения которых на поле Робота появляются фигуры, изображенные на рисунке 5.3. а) б) в) Рис. 5.3 5.6. Переведите Робота в клетку D за три хода (рис. 5.4). а) Напишите три разные программы, делающие это за три хода, б) Может ли Робот попасть в клетку D за четыре хода? за пять ходов? за шесть ходов? Обоснуйте свои ответы. Рис. 5.4 А. Задачи без условий 167 5.7. Робот выполнил программу (см. справа). а) Нарисуйте путь Робота на плоскости. Обозначьте конечное положение Робота буквой D. б) Напишите более короткую программу, переводящую Робота из того же начального положения в клетку D. Сколько команд в вашей короткой программе? 5.8. Ниже приведены четыре программы: вверх влево вверх вправо 'вправо вверх влево ' ‘вниз J вправо вниз влево вниз [ влево закрась вправо вверх влево вправо вправо вниз закрась влево j вправо t I закрась ) } вверх ') влево ' ' влево вверх ! I вправо I I вниз * J вправо 1 вправо вверх вправо вверх вниз вниз вниз влево вниз i вправо ; закрась ) закрась I 5.9. После выполнения каких из этих программ Робот: а) окажется в одной и той же клетке; б) сделает одно и то же число шагов; в) закрасит одни и те же клетки? Робот начал свой путь в клетке А и закончил его в клетке В, выполнив программу (см. справа). Не рисуя пути Робота, напишите более короткую программу, переводящую его из клетки А в клетку В. 5.10. Робот начал свой путь в клетке А и, выполнив некоторую программу, закончил его в клетке В (рис. 5.5). Если Робот начнет свой путь в клетке С, то после выполнения той же программы он закончит его в клетке D. Перерисуйте рисунок в тетрадь и поставьте для каждой буквы С букву D в нужной клетке. 5.11. Робот выполнил программу а (с. 169). а) Нарисуйте в тетради клетчатое поле Робота и закрасьте клетки в соответствии с этой программой, б) Напишите более короткую программу, в результате выполнения которой оказались бы закрашенными те же клетки. влево вниз вниз вниз вправо вправо вверх влево вниз 168 ЗАДАЧНИК а) вниз закрась влево вниз вправо вверх закрась вправо закрась С А - с" -- с — В Рис. 5.5 Рис. 5.6 5.12. Перед началом выполнения некоторой программы Робот находился в клетке А и закончил ее выполнение в клетке С. Клетки, закрашенные в результате выполнения этой программы, показаны на рисунке 5.6. Перерисуйте рисунок в тетрадь и закрасьте клетки, которые закрасил бы Робот, снова выполнив ту же самую программу, но начав свой путь в клетке С. 5.13. На поле Робота стен нет. Имеются две программы. Первая переводит Робота из клетки А в клетку В, вторая — из клетки А в клетку С (рис. 5.7). б) в) А С Рис. 5.7 Робот выполняет сначала первую программу, а затем вторую и попадает из клетки А в клетку D. Перерисуйте рисунки в тетрадь и на каждом из полей обозначьте клетку D. Что произойдет, если Робот выполнит сначала вторую программу, а затем первую? с е 3 словии 169 В ч Рис. 5.8 5.14. Придумайте какую-нибудь картинку из закрашенных клеток и напишите программу ее получения. Чтобы проверить себя, нарисуйте путь Робота и закрасьте клетки в соответствии с программой. 5.15. Клетки на поле Робота закрашены в шахматном порядке. Робот находится на белой клетке (рис. 5.8). На какой клетке — белой или черной — окажется Робот, сделав: а) 1 шаг; б) 2 шага; в) 3 шага; г) 4 шага; д) 18 шагов; е) 124 шага; ж) 43 шага? Как результат зависит от четности числа сделанных шагов? Обоснуйте свой ответ. 5.16. Придумайте две программы для Робота, в результате исполнения каждой из которых он закрашивает 5 клеток. При этом в первой программе должны быть две соседние команды, перестановка которых дает программу, в результате исполнения которой Робот закрашивает 4 клетки, а во второй программе должны быть две соседние команды, перестановка которых дает программу, в результате исполнения которой Робот закрашивает 6 клеток. Укажите, какие две команды нужно переставить в первом и во втором случаях. 5.17. Выполняя некоторую программу. Робот возвраш;ается в исходное положение. Одну из команд в программе стерли, но после выполнения новой программы Робот по-прежнему воз-врапцается в исходное положение. Какая команда стерта? 5.18. Робот прошел по замкнутому маршруту и оказался в той же клетке, с которой начал. Каких команд в программе Робота больше: вправо или влево? вверх или вниз? 5.19. Выполнив некоторую программу. Робот из начальной клетки а) к леп РК> В (F »ис . 5 .9). к б) -I А В А В в) Рис. 5.9 170 ЗАДАЧНИК Каких команд в программе Робота больше и на сколько: вправо или влево? вверх или вниз? 5.20. Выполнив некоторую процедуру, Робот закрасил на поле клетки и получил картинку а, изображенную на рисунке 5.10. а) б) Д) а) Рис. 5.10 ж) 3) Как следует изменить эту процедуру, чтобы закрашенные клетки выглядели, как в вариантах б—з? Напишите все эти процедуры. С этого момента мы считаем, что на поле Робота могут стоять стены, образуя лабиринт. 5.21. Напишите программы, переводящие Робота из клетки А в клетку В в лабиринтах, изображенных на рисунке 5.11. а) Рис. 5.1 1 [ J . 1 — 7 в А. Задачи без условий 5.22. Напишите программы, переводящие Робота из клетки А в клетку В и закрашивающие указанные клетки в лабиринтах, показанных на рисунке 5.12. а) Рис. 5.12 - б) 1 1 1 А |' в А |В 5.23. Программа а переводит Робота по некоторому лабиринту из клетки А в клетку В. Напишите программу, которая переводит Робота из клетки В в клетку А по тому же лабиринту так, что он закрашивает те же клетки и ни разу не натыкается на стены. 5.24. Робот прошел по некоторому лабиринту из клетки А в клетку В, выполнив программу б. Напишите более короткую программу, переводящую Робота по тому же лабиринту из клетки А в клетку В так, что он не натыкается на стену. Поясните свое решение. 5.25. Выполнив процедуру маршрут, в которой не больше 10 команд и нет команды закрась. Робот из клетки А попал в клетку В (рис. 5.13). а) Каков результат выполнения той же процедуры, если начальное положение Робота — клетка С? D? Е? б) Может ли в этой процедуре быть ровно 10 команд? 8 команд? 5.26. Робот находится в коридоре шириной в одну клетку, окаймляющем прямоугольник размером 4X5 (рис. 5.14). Рис. 5.13 D В С А Е Рис. 5.14 а) б) вверх закрась вправо вправо вниз закрась вправо вниз влево закрась вниз вправо вверх вправо вверх влево влево вниз вниз вниз влево вверх 172 ЗАДАЧНИК 5.27. 5.28. а) Напишите программу, раскрашивающую клетки этого коридора в шахматном порядке, б) Пусть коридор окаймляет любой прямоугольник. Верно ли, что клетки такого коридора всегда можно раскрасить в шахматном порядке? Напишите программу рисования вложенных квадратов (рис. 5.15). Напишите программу закрашивания лесенки (рис. 5.16). Рис. 5.15 Рис. 5.16 5.29. Робот находится внутри прямоугольника размером m х п, огороженного стеной. Других стен на поле нет. Может ли Робот обойти все поле, побывав на каждой клетке ровно по одному разу, и вернуться в начальную клетку? Как это зависит от чисел тип? Указание: см. задачу 5.15. 5.30. Робот стоит в левом конце коридора 1X8. Нарисуйте в тетради результат выполнения программ а и б. а) б) ПОВТОРИТЬ 7 РАЗ вправо закрась КОНЕЦ ПОВТОРИТЬ 7 РАЗ закрась вправо КОНЕЦ 5.31. Робот стоит в левом верхнем углу прямоугольника 7 х Ю без внутренних стенок. Нарисуйте в тетради результат выполнения Роботом программы (см. справа). ПОВТОРИТЬ 3 РАЗ закрась вниз вниз ПОВТОРИТЬ 2 РАЗ закрась* вправо закрась вверх КОНЕЦ вниз вправо закрась* вниз КОНЕЦ А Зодачи без условий 173 Отметьте на своем рисунке в тетради клетки, на которых Робот выполнял отмеченную команду закрась. а) Сколько раз Робот выполнил команду закрась? б) Сколько клеток закрашено после выполнения этой программы? 5.32. Робот стоит в левом верхнем углу квадрата 10 х 10 без внутренних стенок. Нарисуйте в тетради результат выполнения Роботом процедуры узор (см. справа), а) Сколько раз Робот выполнил команду закрась? б) Сколько всего закрашенных клеток? в) Сколько клеток Робот красил 1 раз? 2 раза? 3 раза? 4 раза? 6.33. Робот стоит в верхней левой , _ __ клетке прямоугольного поля. Ему разрешается пользоваться только командами вниз и вправо, а) Напишите в каждой клетке поля число разных программ, приводящих Робота в эту клетку, б) Какому простому правилу подчиняются эти числа? 5.34. Робот стоит в верхней левой клетке квадратного поля 8x8, в центре которого ограничен стенами квадрат 4X4. Ему разрешается пользоваться только командами вниз и вправо, а) Напишите в каждой клетке поля число разных программ, приводящих Робота в эту клетку, б) Какому простому правилу подчиняются эти числа? 6^ Чертежник 6.1. Перепишите таблицу в тетрадь, заполняя пропущенные места. ПРОЦ узор НАЧАЛО ПОВТОРИТЬ 5 РАЗ ПОВТОРИТЬ 3 РАЗ закрась вправо КОНЕЦ ПОВТОРИТЬ 3 РАЗ закрась | вниз \ КОНЕЦ I ПОВТОРИТЬ 2 РАЗ i закрась i влево ; вверх закрась ; КОНЕЦ ; КОНЕЦ Начальная точка Команда Чертежника Конечная точка а) (0, 0) переведи в точку (2, 3) ( ) б) (0. 0) сдвинь на вектор (2, 3) ( ) в) (3, 4) переведи в точку (1,2) ( ) г) (3, 4) сдвинь на вектор (1,2) ( ) Д) (-2, -1) сдвинь на вектор ( ) (3, -4) 174 ЗАДАЧНИК Продолжение Начальная точка Команда Чертежника Конечная точка е) (4, 7) переведи в точку ( ) (-2, -8) ж) ( ) сдвинь на вектор (2, -3) (2, -1) 3) ( ) переведи в точку (5, 2) (5, 2) и) ( ) переведи в точку (-3, 4) (1- 0) 6.2. Чертежник, выполнив команду сдвинь на вектор, переместил перо из точки (2, 4) в точку (5, -3). В какую точку переместится перо Чертежника из точки (-1, 2) после выполнения той же команды? 6.3. Какие числа стояли в команде сдвинь на вектор, если, выполнив ее. Чертежник переместил перо из точки (а, Ь) в точку (х, у)? 6.4. Чертежник, выполнив команду сдвинь на вектор, переместил перо из точки (1, -3) в точку (-4, 9). Из какой точки перо Чертежника переместится в точку (7, 15) после выполнения той же команды? 6.5. При выполнении процедуры, не содержащей команды переведи в точку, перо Чертежника из точки с координатами (2, 3) попало в точку с координатами (9, -5). В какую точку попадет перо из точки (-6, 7) после выполнения той же процедуры? 6.6. Перо расположено в начале координат и опущено. Напишите программу, выполнив которую Чертежник нарисует фигуру, изображенную на рисунке 6.1: а) используя только команды переведи в точку; б) используя только команды сдвинь на вектор. Что нарисует каждая из ваших программ, если начальное положение пера — точка с координатами (4, 0)? А. отдачи без условий 175 6.7. а) Что нарисует Чертежник, выполнив программу а? б) Как результат зависит от начального положения пера? 6.8. Что нарисует Чертежник, выполнив программу бЧ а) подними перо переведи в точку опусти перо переведи в точку переведи в точку переведи в точку переведи в точку переведи в точку переведи в точку переведи в точку подними перо переведи в точку опусти перо переведи в точку переведи в точку подними перо переведи в точку опусти перо переведи в точку 1 б) t подними 1 перо (-2. -4) ! : переведи в точку (-4 , -2) ( 1 опусти перо (-2, 0) переведи , переведи в точку (1, 3) (2, 0) 1 в точку (1, 4) (2. -4) переведи в точку (4, 3) (0, -2) ( i переведи в точку (2, 3) (-2, -2) ( ( переведи в точку (1, 0) (0, -4) 1 J переведи в точку (1, -3) (0, -2) , переведи в точку (2. -4) , переведи в точку (2, -3) (-2,0) ; , переведи в точку (1. -3) . переведи в точку (1, -2) (0. 2) , , переведи в точку (0, -1) (2, 0) ' переведи в точку (-1 , -2) переведи в точку (-1 , -4) (-2, -4) ' переведи в точку (0, -5) переведи в точку (0, -4) (2, -4) ' переведи в точку (-1 , -4) - — J. ' переведи в точку (-1 . -3) переведи в точку (-2 , -2) переведи в точку (-4 , -2) 6.9. а) Что нарисует Чертежник, выполнив программу (см. справа)? б) Чему равна во всех командах сдвинь на вектор сумма первых координат? сумма вторых координат? в) В какой точке оказалось перо по окончании работы программы? подними перо переведи в точку опусти перо сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор сдвинь на вектор (-2, 0) (1, (2, (1, (0. (1, 1) 0) -1) 1) 0) (1, 2) (-1. -1) (-1, 1) (0, -1) (-2, 1) (-2, -1) (-1, 2) (1, -4) ^76 ЗАДАЧНИК 6.10. Вася написал процедуру для Чертежника, выполняя которую опущенное перо начертило замкнутую ломаную и вернулось в начальную точку. Два числа в одной из команд этой процедуры стерлись. Какие это числа? Нарисуйте Васину линию. 6.11. Восстановите числа, пропущенные в процедуре замкнутая ломаная 2, выполняя которую Чертежник возвращается в начальную точку. Нарисуйте эту ломаную при начальном положении пера в точке (-4, -3). Перо опущено. 6.12. Вася придумал процедуру, рисующую фигуру рядом с началом координат. Как, используя координаты вершин Васиной фигуры, написать процедуру, рисующую такую же фигуру в любом месте? Напишите эту процедуру, воспользовавшись задачей 6.3. Проверьте свое решение рисунком. 6.13. а) В процедуре кривая 1 все вторые координаты в командах переведи в точку заменили на противоположные. Какую фигуру рисует процедура кривая 1? новая процедура кривая 2? ПРОЦ замкнутая ломаная 1 НАЧАЛО сдвинь на вектор (2, -5) сдвинь на вектор (2, 6) сдвинь на вектор (2, -5) сдвинь на вектор (5, 0) сдвинь на вектор (...) КОНЕЦ ПРОЦ моя звезда НАЧАЛО опусти перо сдвинь на вектор ( сдвинь на вектор ( сдвинь на вектор ( сдвинь на вектор ( сдвинь на вектор ( КОНЕЦ ПРОЦ замкнутая ломаная 2 НАЧАЛО сдвинь на вектор (3, 2) сдвинь на вектор (5, ...) сдвинь на вектор (-4, -2) сдвинь на вектор (..., 3) сдвинь на вектор (-3, -5) КОНЕЦ ПРОЦ Васина звезда НАЧАЛО подними перо переведи в точку (1,0) опусти перо переведи в точку (6, 3) переведи в точку (0, 3) переведи в точку (5, 0) переведи в точку (3, 5) переведи в точку (1, 0) КОНЕЦ 3 угповии 177 ПРОЦ кривая 1 НАЧАЛО подними перо переведи в точку опусти перо переведи в точку переведи в точку переведи в точку переведи в точку переведи в точку переведи в точку переведи в точку переведи в точку КОНЕЦ (1. 1) (2, 2) (5, 2) (6, 1) (6, 5) (4, 3) (2, 4) (0, 3) (1. 1) ПРОЦ кривая 2 НАЧАЛО подними перо переведи в точку (1, -1) опусти перо переведи в точку (2, -2) переведи в точку (5, -2) переведи в точку (6, -1) переведи в точку (6, -5) переведи в точку (4, -3) переведи в точку (2, -4) переведи в точку (О, -3) переведи в точку (1, -1) КОНЕЦ Проверьте свое решение, б) Если заменить на противоположные все первые координаты в командах переведи в точку процедуры кривая 1, то получится еш;е одна процедура кривая 3. Какую фигуру рисует она? 6.14. а) В процедуре дом 1 все первые координаты в командах сдвинь на вектор заменили на противоположные. Какую фигуру нарисует новая процедура дом 2? L ПРОЦ дом 1 НАЧАЛО сдвинь на вектор (4, 0) сдвинь на вектор (0, 2) сдвинь на вектор (-2, 0) сдвинь на вектор (0, -2) сдвинь на вектор (2, 2) сдвинь на вектор (0, 2) сдвинь на вектор (-4, 0) сдвинь на вектор (0, -4) сдвинь на вектор (4, 4) сдвинь на вектор (-2, 2) сдвинь на вектор (-2, -2) сдвинь на вектор (-4, -4) сдвинь на вектор (-4, 0) КОНЕЦ I ПРОЦ дом 2 НАЧАЛО сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на сдвинь на КОНЕЦ вектор вектор вектор вектор вектор вектор вектор вектор вектор вектор вектор вектор вектор (-4, 0) (0. 2) (-2, 0) (0. -2) (-2, 2) (0, 2) (4, 0) (0, -4) (-4. 4) (2, 2) (2, -2) (-4. -4) (4. 0) А если в командах сдвинь на вектор заменить на противоположные: б) вторые координаты (процедура дом 4); в) первые и вторые координаты (процедура дом 3); г) какую картинку нарисует программа а? 178 ЗАДАЧНИК а) подними перо переведи в точку (6, 6) . опусти перо I' дом 1 дом 2 дом 3 дом 4 6.15. Процедура, выполнив которую Чертежник нарисовал фигуру, изображенную на рисунке 6.2, содержит команды переведи в точку и команды сдвинь на вектор. Вторую координату в каждой из этих команд заменили на противоположную. Что нарисует Чертежник, выполняя новую процедуру из того же начального положения пера? 6.16. Перо Чертежника находилось в начале координат. Выполнив процедуру машина, содержащую только команды сдвинь на вектор. Чертежник нарисовал машину, как на рисунке 6.3. Перо при этом вернулось в начало координат. В этой процедуре все первые координаты заменили на противоположные А. Задачи без условий 179 и получили процедуру машина 1. Что нарисует Чертежник, выполнив каждую из следующих программ: а) подними перо переведи в точку (2, 2) опусти перо машина 1 машина 1 б) подними перо переведи в точку (-5, 2) опусти перо машина 6.17. В процедуре машина (задача 6.16) все вторые координаты команд заменили на противоположные. Что теперь нарисует Чертежник, если опущенное перо находится в начале координат? 6.18. Перо Чертежника опущено и находится в начале координат. Попробуйте описать, как изменяется результат выполнения Чертежником некоторой процедуры, если в каждой команде этой процедуры заменить на противоположные: а) первые координаты; б) вторые координаты; в) и первые, и вторые координаты; г) как зависит ответ в предыдущих задачах от того, есть ли в этой процедуре команды переведи в точку? Чтобы проверить свои решения, напишите программы. 6.19. В процедуре указатель 1 все координаты в каждой из команд переведи в точку и сдвинь на вектор поменяли местами. Что нарисует Чертежник, выполнив первоначальную и измененную процедуры? ПРОЦ указатель 1 НАЧАЛО подними перо переведи в точку (5, 3) опусти перо сдвинь на вектор (О, -4) сдвинь на вектор (-2, О) сдвинь на вектор (-1, -1) сдвинь на вектор (1, -1) сдвинь на вектор (5, О) сдвинь на вектор (О, 2) сдвинь на вектор (-3, О) КОНЕЦ ПРОЦ указатель 2 НАЧАЛО подними перо переведи в точку (3, 5) опусти перо сдвинь на вектор (-4, 0) сдвинь на вектор (0, -2) сдвинь на вектор (-1, -1) сдвинь на вектор (-1, 1) сдвинь на вектор (0, 5) сдвинь на вектор (2, 0) сдвинь на вектор (0, -3) КОНЕЦ 6.20. Аня написала процедуру, которую она назвала бабочка на цветке. Ее процедура рисует картинку, как на рисунке 6.4, и использует только команды сдвинь на вектор, подними перо и опусти перо. 180 ЗАДАЧНИК Вова поменял местами в Аниной процедуре координаты во всех командах. Какую картинку нарисует Чертежник, выполняя новую процедуру? Попробуйте написать процедуру, рисующую Анину картинку. Что нарисует ваша процедура, если в ней все координаты в командах сдвинь на вектор поменять местами, а начальное положение пера — точка с координатами (О, 4)? 6.21. а) Перо Чертежника опущено и находится в начале координат. Попробуйте сформулировать, как изменяется результат выполнения Чертежником некоторой процедуры, если в командах этой процедуры координаты поменять местами, б) Как зависит ответ на предыдущий вопрос от того, есть ли в этой процедуре команды переведи в точку? Проверьте решения на примерах своих программ. 6.22. Как нужно изменить аргументы команд (координаты векторов) сдвинь на вектор в процедуре дом 1 из задачи 6.13 (назовем новую процедуру домик), чтобы, выполнив процедуру домик. Чертежник нарисовал дом вдвое меньшего размера? 6.23. Используя процедуры дом 1 и домик, научите Чертежника рисовать рядом два дома, большой и маленький, как показано на рисунке 6.5 (назовем эту процедуру два дома). 181 6.24. Используя процедуру два дома, научите Чертежника рисовать улицу, изображенную на рисунке 6.6. 6.25. Как изменится картинка, которую рисует Чертежник, выполняя указанную справа программу, если в каждой из команд поменять местами координаты, а потом у всех новых первых координат поменять знак на противоположный? 6.26. Перо Чертежника опущено и находится в начале координат. Аня написала процедуру, выполнив которую Чертежник нарисовал картинку, изображенную на рисунке 6.7. подними перо переведи в точку (4, О) опусти перо сдвинь на вектор (О, 3) сдвинь на вектор (-2, О) сдвинь на вектор (-1, 1) сдвинь на вектор (1, 1) сдвинь на вектор (5, 0) сдвинь на вектор (0, -2) сдвинь на вектор (-3, 0) 182 ЗАДАЧНИК Два мальчика, Вова и Петя, решили подшутить над Аней и изменить картинку, поменяв координаты в ее программе. Вова предлагал поменять местами координаты во всех командах, а Петя изменить знак первой координаты во всех командах. Каждый из них осуществил задуманное, ничего не зная о другом. Что нарисует новая программа, если перо находится в начале координат и первым проделал свое изменение: а) Вова; б) Петя? 6.27. Процедура зигзаг 1 делает чертеж, изображенный на картинке а рисунка 6.8. Какие изменения нужно произвести с командами этой процедуры, чтобы получить чертежи б—г рисунка 6.8 и чертежи а—в рисунка 6.9? Напишите соответствующие процедуры. А. Задачи без условий 183 Рис. 6.9 2 3 4 5 X 6.28. Чертежник выполнил программу и нарисовал картинку, приведенную на рисунке 6.10. подними перо , переведи в точку (0, 0) опусти перо картинка 184 ЗАДАЧНИК ПРОЦ картинка НАЧАЛО сдвинь на вектор (8, 0) сдвинь на вектор (0, 3) сдвинь на вектор (-8, 0) сдвинь на вектор (0, -3) сдвинь на вектор (8, 0) сдвинь на вектор (0, 5) сдвинь на вектор (-8, -5) КОНЕЦ Как нужно изменить последнюю команду в процедуре картинка, чтобы, выполнив ту же программу. Чертежник нарисовал картинку, приведенную на рисунке 6.11? 6.29. Чертежник выполнил программу и нарисовал картинку, приведенную на рисунке 6.12. подними перо переведи в точку (0, 0) опусти перо картинка 1 ПРОЦ картинка 1 НАЧАЛО сдвинь на вектор (7, 0) сдвинь на вектор (-7, 5) сдвинь на вектор (5, 1) сдвинь на вектор (-5, -6) КОНЕЦ Как нужно изменить последнюю команду в процедуре картинка 1, чтобы, выполнив ту же программу. Чертежник нарисовал картинку, приведенную на рисунке 6.13? Задачи без условий 18^ 6.30. Чертежник выполнил программу подними перо переведи в точку (3, 1) опусти перо абракадабра и нарисовал картинку (рис. 6.14), не проводя ни одной линии дважды. В процедуре абракадабра нет команды подними перо. Каковы координаты конечного положения пера Чертежника? 6.31. Научите Чертежника рисовать картинки, изображенные на рисунке 6.15 (напишите для каждой из картинок процедуры, используя только команды подними перо, опусти перо и сдвинь на вектор): ПРОЦ кошка Рис. 6.15 ПРОЦ собака 18^ ЗАДАЧНИК г) Составьте программу рисования деревни с использованием этих процедур. 6.32. Учительница алгоритмики Процедура Цикловна написала процедуру, рисующую приближенно график функции у = (при этом переменная д: меняется на промежутке [О, 3]), и скопировала эту процедуру всем ребятам. ПРОЦ парабола НАЧАЛО опусти сдвинь сдвинь сдвинь сдвинь сдвинь сдвинь сдвинь сдвинь сдвинь сдвинь КОНЕЦ перо на вектор на вектор на вектор на вектор на вектор на вектор на вектор на вектор на вектор на вектор (0.3, (0.3, (0.3, (0.3, (0.3, (0.3, (0.3, (0.3, (0.3, (0.3, 0.09) 0.27) 0.45) 0.63) 0.81) 0.99) 1.17) 1.35) 1.53) 1.71) а) График какой функции приближенно нарисует Чертежник, выполнив программу а? На каком промежутке будет меняться переменная х1 б) Саша решил поменять в процедуре парабола вторые координаты во всех командах на противоположные (процедура Сашина парабола). График какой функции приближенно нарисует Чертежник, выполнив программу б? На каком промежутке будет меняться переменная х1 в) Петя решил поменять в динаты во всех командах а) ( подними перо ‘ переведи в точку (2, -1) ^ парабола б) в) подними перо переведи в точку (-2, -3) Сашина парабола подними перо переведи в точку (4, 1) петина парабола процедуре парабола первые коор-на противоположные (процедура петина парабола). График какой функции приближенно нарисует Чертежник, выполнив программу в? На каком отрезке будет меняться переменная л:? А. Задачи без условий 187 г) Д) е) ж) подними перо переведи в точку (-4, О) колина парабола подними перо переведи в точку (6, 1) вовина парабола подними перо переведи в точку (О, О) парабола 1 подними перо переведи в точку (О, -5) опусти перо парабола 2 г) Коля решил поменять в процедуре парабола местами первые и вторые координаты во всех командах (процедура колина парабола). График какой функции приближенно нарисует Чертежник, выполнив программу г? На каком промежутке будет меняться переменная д) Вова решил поменять в процедуре парабола местами первые и вторые координаты во всех командах и изменить знаки всех координат на противоположные (процедура вовина парабола). График какой функции приближенно нарисует Чертежник, выполнив программу д? На каком промежутке будет меняться переменная лг? е) График какой функции приближенно нарисует Чертежник, выполнив программу el На каком промежутке будет меняться переменная х, если в процедуре парабола увеличить все первые координаты вдвое (процедура парабола 1)? ж) График какой функции приближенно нарисует Чертежник, выполнив программу ж1 На каком промежутке будет меняться переменная х, если в процедуре парабола уменьшить все первые координаты втрое (процедура парабола 2)? 6.33. Используя процедуру парабола, напишите программу приближенного изображения графиков функций: а) г/ = (х - 5)^; б) г/ = (х -f 1)^ - 3; в) г/ = х^ - бх -I- 10; г) у = -х^ - 4х -I- 1; д) X = (у -I- 2f-, е) X = -(у - 1)^ -Ь 2 на подходящих отрезках. 6.34. Напишите процедуру, приближенно рисующую параболу г/ = х^ на отрезках: а) [1, 2]; б) [-1, 3]; в) [-5, -3]; г) [-2, 2] по 5, 10, 20 точкам. 6.35. Напишите такую процедуру треть ПОВТОРИТЬ 3 РАЗ квадрата, чтобы выполнив програм- треть квадрата му Чертежник нарисовал квадрат, не КОНЕЦ проводя ни одного отрезка дважды. 188 ЗА 7} Черепаха 7.1. Вычислив значения арифметических выражений, заполните пропущенные аргументы в командах: а) назад (7 + 13-3) — то же самое, что назад ( ); б) вперед ((3 + 39) /2-9) — то же самое, что вперед ( ); в) назад (1 *2*3*4 - 13) — то же самое, что назад ( ); г) назад (13*(3 - (-1 + 22) / 7) + 3) — то же самое, что назад ( ). Договоримся, что безразлично, какую из команд выполнить — вперед (-5) или назад (5), ведь пройти 5 шагов вперед — это все равно что отступить на 5 шагов назад. Конечно, команда назад (-12) означает то же самое, что команда вперед (12). А команда вперед (О) или назад (О) означает, что Черепаха «делает О шагов», т. е. остается на месте. 7.2. Вычислив значения арифметических выражений, заполните пропуски в следующих командах: а) вперед (7*8 - 6*4) — то же самое, что назад ( ); б) вперед ((6*8 - 7*3)/9 - 2*3) — то же самое, что назад ( ); в) назад (7*8*9/6 - 10*10) — то же самое, что назад ( ); г) назад (3*4*5 - 4*5*6) — то же самое, что вперед ( ). 7.3. Какой командой можно заменить следующие пары команд, если хвост Черепахи поднят? а) назад (-4) вперед (5) б) назад (7) назад (-8) в) вперед (-8) вперед (-3) 7.4. а) Хвост Черепахи поднят. Верно ли, что выполнить подряд две команды вперед (а) и вперед (Ь) все равно что выполнить одну команду вперед (а + Ь) ? Рассмотрите все случаи положительных и отрицательных а и Ь. б) Хвост Черепахи поднят. Верно ли, что выполнить подряд две команды вперед (а) и назад (Ь) все равно что выполнить одну команду вперед (а - Ь) ? А. Задачи без условий 189 Изменятся ли ответы в пунктах а и б, если хвост Черепахи опущен? А если к тому же числа а и Ь положительны? 7.5. На рисунке 7.1 изображено начальное положение Черепахи для каждого из случаев а—ж. а) б) Рис. 7.1 в) ^0“ г) Д) t t е) ж) 30^ \ Нарисуйте в тетради ее конечное положение после выполнения соответствующих команд, приведенных ниже. Если вам трудно рисовать Черепаху, то изображайте ее в виде стрелочки, повернутой в том направлении, куда Черепаха смотрит. а) j влево (120) j I вправо (180) j 6)Q влево (90) t в) г влево (60) \ влево (60) вправо (30) г) ; влево (750) д) I влево (30) е) f влево (150) ж)I вправо (32) вправо (56) вправо (122) ■J 7.6. На рисунке 7.2 указаны начальное и конечное положения Черепахи. Напишите, какую команду поворота она могла выполнить. 7.7. Замените каждую из следующих программ одной командой, выполнение которой дает такой же результат. начальное положение Рис. 7.2 а) вправо (30) влево (120) влево (50) влево (250) б) I влево (140) вправо (260) вправо (-110) вправо (-240) | в) ; вправо (1000) ^ вправо (340) I влево (-100) 190 ЗАДАЧНИК 7.8. Черепаха выполнила следующие программы: б) I опусти хвост в) f вправо (90) а) опусти хвост вперед (20) влево (90) вперед (20) подними хвост I вперед (20) вправо (90) подними хвост опусти хвост I вперед (30) назад (15) вправо (60) ^ подними хвост Нарисуйте след, оставленный Черепахой (начальное положение Черепахи любое). 7.9. Напишите программы рисования картинок, изображенных на рисунке 7.3. а) б) Рис. 7.3 Д) 3) Удобные размеры выберите сами. 7.10. Черепаха из начального положения выполнила программу (см. справа), а) Нарисуйте ее след, б) Напишите более короткую программу, выполнив которую Черепаха оставит тот же след. 7.11. В программе Черепахи вычеркнули одну команду. Выполнив из того же начального положения новую программу. Черепаха оставила тот же след и закончила программу в том же самом положении. Какая именно команда могла быть вычеркнута из программы, если вычеркнутая команда: а) команда поворота; б) команда движения? опусти хвост вперед (30) назад (20) вперед (10) вправо (90) влево (210) вперед (20) подними хвост А. Зодачи без условий 191 б) в) г) Рис. 7.4 7.12. Черепаха выполнила прюграмму (см. справа). Не рисуя ее следа, напишите более короткую программу, оставляюш;ую тот же след и переводящую Черепаху в то же положение из начального. 7.13. Выполнив некоторую программу. Черепаха из начального положения пришла в конечное, оставив след а (рис. 7.4). Нарисуйте ее след и конечное положение после выполнения той же программы, если начальное положение Черепахи задается рисунками б, в, г. 7.14. Черепаха выполнила программу (см. справа). а) Нарисуйте след, оставленный Черепахой. б) В этой программе все команды поворотов заменили на противоположные (вправо (а) на влево (а) и наоборот). Какую картинку нарисует Черепаха, выполнив новую программу с тем же начальным положением? Проверьте свое решение. 45' опусти хвост вперед (20) назад (10) вправо (60) влево (150) подними хвост вперед (40) вправо (250) влево (-110) назад (30) вперед (-10) опусти хвост вправо (90) подними хвост опусти хвост вперед (40) вправо (90) вперед (40) влево (135) вперед (40) подними хвост 7.15. Черепаха выполнила программу (см. справа). а) Нарисуйте след, оставленный Черепахой. б) В этой программе все команды движения заменили на противоположные (вперед (а) на назад (а) и наоборот). Какую картинку нарисует Черепаха, выполнив новую программу с тем же начальным положением? Проверьте свое решение. опусти хвост вперед (50) влево (30) вперед (50) вправо(120) вперед (50) подними хвост 192 АДАЧИИК 7.16. В процедуре топор 1 все команды поворотов и движений заменили на противоположные. Новая процедура называется топор 2. Какую картинку нарисует Черепаха, выполнив следующие программы из одного и того же начального положения: а) топор 1 б) J топор 2 “ в) вправо (180) топор 2 ПРОЦ топор 1 НАЧАЛО опусти хвост вперед (50) влево (60) ПОВТОРИ 3 РАЗ вперед (20) влево (120) КОНЕЦ вправо (60) назад (50) подними хвост КОНЕЦ Проверьте свои решения. 7.17. Черепаха, выполнив некоторую программу, из начального положения пришла в конечное, оставив след, изображенный на рисунке 7.5. В программе все команды поворотов поменяли на противоположные (каждую команду вправо (а) заменили на команду влево (а) и наоборот). Нарисуйте конечное положение и след, оставленный Черепахой после выполнения новой программы при том же начальном положении. 7.18. Черепаха, выполнив некоторую программу, из начального положения пришла в конечное, оставив след, изображенный на рисунке 7.6. В программе все команды движения поменяли на противоположные (каждую команду вперед (а) заменили на команду назад (а) и наоборот). Нарисуйте конечное положение и след, оставленный Черепахой после выполнения новой программы при том же начальном положении. конечное положение начальное положение Рис. 7.5 начальное положение конечное положение Рис. 7.6 А. Задачи без условий 193 7.19. Черепаха, выполнив некоторую программу, из начального положения пришла в конечное, оставив след, показанный на рисунке 7.7. В программе все команды движения и команды поворотов заменили на противоположные (каждую команду вперед (а) заменили на команду назад (а), каждую команду назад (а) — на команду вперед (а), каждую команду вправо (а) — на команду влево (а), а команду влево (а) — на команду вправо (а)). Нарисуйте конечное положение и след, оставленный Черепахой после выполнения новой программы из того же начального положения. 7.20. Черепаха, выполнив процедуру флаг из начального положения, оставила след, изображенный на рисунке 7.8. конечное положение начальное положение Рис. 7.7 конечное положение Рис. 7.8 Какой след оставит Черепаха, выполнив каждую из следующих программ: а) вправо (45) флаг б) I; влево (240) флаг в) влево (135) флаг Как изменятся ответы в задаче, если мы не знаем, из какого начального положения Черепаха нарисовала этот рисунок? Можем ли мы сказать, каково конечное положение Черепахи в задачах 7.17, 7.18 и 7.19, если мы не знаем конечного положения Черепахи после выполнения процедуры флаг? 7.21. Черепаха, выполнив программу влево (120) флаг 1 вправо (90) Рис. 7.9 из какого-то начального положения, оставила след, изображенный на рисунке, и оказалась в конечном положении, указанном на рисунке 7.9. Какой след оставит Черепаха, выполнив процедуру флаг 1? Каково конечное положение Черепахи? 194 ЗАДАЧНИК 7.22. Выполнив процедуру флаг 2, Черепаха нарисовала такой флаг, как на картинке а (рис. 7.10). Какие изменения следует произвести в командах этой процедуры, чтобы флаг выглядел так, как на картинках б—ж1 Рис. 7.10 7.23. Черепаха выполнила программу а. В этой программе все аргументы команд движения разделили на 2. Нарисуйте: а) какую картинку нарисовала Черепаха первоначально; б) какую картинку она нарисует, выполнив новую программу. 7.24. Черепаха выполнила программу б и нарисовала домик, показанный на рисунке 7.11 (начальное положение Черепахи отмечено). Каково конечное положение Черепахи? Как нужно изменить аргументы команд, чтобы, выполняя новую программу. Черепаха нарисовала домик: а) в 2 раза меньшего размера; б) в 3 раза большего размера? а) опусти хвост ПОВТОРИТЬ 3 РАЗ вперед (80) вправо (120) КОНЕЦ назад (40) ПОВТОРИТЬ 4 РАЗ назад (80) вправо (90) КОНЕЦ вперед (40) подними хвост б) опусти хвост ПОВТОРИТЬ 4 РАЗ вперед (40) вправо (90) КОНЕЦ вперед (40) вправо (30) ПОВТОРИТЬ 3 РАЗ вперед (40) вправо (120) КОНЕЦ влево (30) назад (40) подними хвост А. Задачи без условий 195 7.25. Черепаха нарисовала правильный треугольник и вернулась в первоначальное положение. Перепишите программу а Черепахи в тетрадь, вставив недостающие аргументы в команды. 7.26. Черепаха выполнила программу б. Нарисуйте в тетради след и положения Черепахи и Ленивой Черепахи после каждой команды. а) На какой угол повернулась Ленивая Черепаха, выполняя эту программу? б) Сколько оборотов против часовой стрелки она совершила? а) опусти хвост вперед (20) влево ( ) вперед (20) влево ( ) вперед (20) влево ( ) подними хвост t б) i опусти хвост ) вперед (20) f влево (60) ^ назад (20) ' влево (60) ' вперед (40) ! влево (150) I вперед (40) Е вправо (90) I назад (30) • влево (180) I подними хвост Рис. 7.12 7.27. Черепаха опустила хвост, нарисовала правильный пятиугольник и вернулась в начальное положение. В каждой вершине она делала один поворот на угол, меньший 180° (рис. 7.12). а) На какой угол повернулась Ленивая Черепаха, выполнявшая вместе с Черепахой эту программу? б) Сколько поворотов она сделала? в) Каждый ли раз она поворачивалась на один и тот же угол? На какой именно угол она поворачивалась? г) Перепишите в тетрадь и допишите процедуру в, выполняя которую Черепаха нарисует правильный пятиугольник. в) ^ ПРОЦ правильный пятиугольник НАЧАЛО опусти хвост ■ ПОВТОРИТЬ 5 РАЗ вперед (40) влево ( ) ’ КОНЕЦ < подними хвост КОНЕЦ 196 ЗАДАЧНИК 7.28. Черепаха опустила хвост, нарисовала правильный семиугольник и вернулась в начальное положение. В каждой вершине она делала один поворот на угол, меньший 180° (рис. 7.13). а) На какой угол повернулась Ленивая Черепаха, выполнявшая вместе с Черепахой эту программу? б) Сколько поворотов она сделала? в) Каждый ли раз она поворачивалась на один и тот же угол? На какой именно угол она поворачивалась? г) Перепишите в тетрадь и допишите процедуру, выполняя которую Черепаха нарисует правильный семиугольник. ПРОЦ правильный семиугольник НАЧАЛО опусти хвост ПОВТОРИТЬ 7 РАЗ вперед (30) вправо ( ) КОНЕЦ подними хвост КОНЕЦ 7.29. Напишите процедуры, выполняя которые Черепаха нарисует: а) правильный 6-угольник (длина стороны 30); б) правильный 8-угольник (длина стороны 20); в) правильный 9-угольник (длина стороны 10); г) правильный 180-угольник (длина стороны 1). На что похож ваш правильный 180-угольник? 7.30. Черепаха опустила хвост, нарисовала правильную семиугольную звездочку и вернулась в начальное положение. В каждой вершине она делала один поворот на угол, меньший 180° (рис. 7.14). а) Сколько оборотов сделала Ленивая Черепаха, выполнявшая вместе с Черепахой эту программу? б) На какой угол она повернулась? в) Сколько раз она поворачивалась? г) Каждый ли раз она поворачивалась на один и тот же угол? На какой именно угол она поворачивалась? д) Допишите процедуру, выполняя которую Черепаха нарисует правильную семиугольную звездочку. Рис. 7.13 ..Задачи без условий ПРОЦ правильная 7-угольная звезда НАЧАЛО опусти хвост ПОВТОРИТЬ 7 РАЗ вперед (40) влево ( ) КОНЕЦ подними хвост КОНЕЦ 7.31. Напишите процедуры, выполняя которые Черепаха нарисует фигуры, изображенные на рисунке 7.15: а) правильную 7-угольную звезду (длина стороны 30); б) правильную 8-угольную звезду (длина стороны 30); в) правильную 9-угольную звезду (длина стороны 30); г) правильную 9-угольную звезду (длина стороны 30); д) бывают ли другие правильные 9-угольные звезды. Рис. 7.15 7.32. Черепаха с опущенным хвостом, выполнив некоторую программу, не содержащую циклов и команд управления хвостом, оказалась в первоначальном положении и нарисовала замкнутую ломаную. Первые 4 команды программы переставили в ее конец. Верно ли, что начальное и конечное положения Черепахи после выполнения новой программы совпадают? Верно ли, что Черепаха нарисует замкнутую ломаную? 7.33. Черепаха с опущенным хвостом выполнила некоторую программу, не содержащую циклов и команд управления хвостом. После этого команды в программе переставили и Черепаха выполнила новую программу при том же начальном положении. Верно ли, что конечные положения Черепахи после выполнения новой и старой программ совпадают? Верно ли, что в обоих случаях Черепаха оставит одинаковый след? 198 ЗАДАЧНИК 7.34. Напишите процедуры, выполняя которые Черепаха нарисует картинки, изображенные на рисунках 7.16 и 7.17. Удобные размеры выберите сами. а) б) в) е) ж) 3) и) к) л) Рис. 7.16 м) А. Задачи без условий 199 а) 6) в) 7 \ / \ / \ / П U и) «) л) Рис. 7.17 7.35. Как вы знаете, окружность — это множество точек, равноудаленных от одной точки, центра окружности. Напишите процедуру рисования окружности по этому определению. (Можно, например, нарисовать 360 точек на расстоянии 30 от центра.) 200 ЗАДАЧИ И К в задачах 7.36 и 7.37 предполагается, что в начальном положении Черепаха смотрит вертикально вверх и ее хвост опущен. 7.36. Черепаха, выполнив процедуру знак, нарисовала картинку, изображенную на рисунке 7.18, и возвратилась в начальное положение (сторона квадрата 25). Какую картинку нарисует Черепаха, выполнив каждую из следующих программ: а) ПОВТОРИТЬ 3 РАЗ вперед (50) знак вправо (120) КОНЕЦ б) ПОВТОРИТЬ 3 РАЗ вперед (50) вправо (120) знак КОНЕЦ в) ПОВТОРИТЬ 3 РАЗ вперед (50) знак влево (120) КОНЕЦ г) ПОВТОРИТЬ 8 РАЗ вперед (50) знак назад (50) влево КОНЕЦ 7.37. Черепаха, выполняя процедуру флажок, рисует картинку, показанную на рисунке 7.19, и возвращается в начальное положение (длина древка 30). Рис. 7.19 а) Какую картинку нарисует Черепаха, выполнив программу а? б) Процедуру флажок использовали в новой процедуре флажок 1 (программа б). Какую картинку нарисует Черепаха, выполнив программу в? а) ПОВТОРИТЬ 6 РАЗ вперед (50) флажок назад (50) вправо (60) КОНЕЦ б) ПРОЦ флажок 1 НАЧАЛО флажок вправо (30) КОНЕЦ '« ^ без условий 201 в) ПОВТОРИТЬ 6 РАЗ ' вперед (50) - флажок 1 назад (50) вправо (60) КОНЕЦ 7.38. Вова написал три процедуры квад 90, квад 30 и квад 10, выполняя которые Черепаха рисует квадраты со сторонами 90, 30 и 10 соответственно. ПРОЦ квад 90 НАЧАЛО опусти хвост ПОВТОРИТЬ 4 РАЗ вперед (90) вправо (90) КОНЕЦ подними хвост КОНЕЦ ПРОЦ квад 30 НАЧАЛО опусти хвост ПОВТОРИТЬ 4 РАЗ вперед (30) вправо (90) КОНЕЦ подними хвост КОНЕЦ ПРОЦ квад 10 НАЧАЛО опусти хвост ПОВТОРИТЬ 4 РАЗ вперед (10) вправо (90) КОНЕЦ подними хвост КОНЕЦ Ира решила подшутить над ним и после уроков изменила две первые процедуры, теперь они выглядят так: ПРОЦ квад 90 НАЧАЛО опусти хвост ПОВТОРИТЬ 4 РАЗ квад 30 вперед (90) вправо (90) КОНЕЦ подними хвост КОНЕЦ ПРОЦ квад 30 НАЧАЛО опусти хвост ПОВТОРИТЬ 4 РАЗ квад 10 вперед (30) вправо (90) КОНЕЦ подними хвост КОНЕЦ 202 ЗАДАЧИ/." Не зная этого, Вова попросил Черепаху выполнить процедуру квад 90. Какую картинку нарисовала ему Черепаха? Сколько на ней квадратиков со стороной 10? 8. Ханойская башня в учебнике выводится оптимальный алгоритм переноса Ханойской башни. Для того чтобы перенести башню из п кружков со стержня А на стержень В за наименьшее число ходов, нужно сначала перенести первые (п - 1) кружков со стержня А на стержень С, затем перенести самый большой кружок со стержня А на стержень В, потом перенести башню из (п - 1) кружков со стержня С на стержень В. ВНИМАНИЕ! Этот алгоритм записывается совершенно по-разному в зависимости от выбранного набора команд для Исполнителя Ханойская башня. Но ходы в игре от этого не меняются. В рисунках ко всем задачам самое левое поле — поле А, среднее — поле В, а правое — поле С (рис. 8.1). А В Рис. 8.1 8.1. На рисунке 8.2 изображено несколько положений кружков на стержнях. 1) М 2) 3) 1 2 3 i 6 5 i 4 1 2 1 1 “I 1 1 6 1 ■ 5 I I 4 i Рис. 8.2 А. Зада Ь е 3 с л о в и и 203 2 4 3 4 2 5 3 Можно ли эти положения получить из начального положения с соблюдением правил игры? Если можно, то как? Постарайтесь написать программы, требующие наименьшего числа ходов. 8.2. На рисунке 8.3 приведено положение кружков после некоторой команды при исполнении оптимального алгоритма переноса башни из четырех кружков со стержня А на стержень В. а) Сколько ходов уже было сделано? б) Сколько ходов осталось сделать? в) Какой ход был последним? г) Каким должен быть следующий ход? 1) 2) 1_з_ 3) 2 : Рис. 8.3 8.3. Та же задача, но для пяти кружков (рис. 8.4). Рис. 8.4 204 ЗАДАЧНИК 1) 1 2 ; 3 1 5 i 1 4 1 2) 1 ! 2^ 5 ! . 3 ! i 4 ; 3) 1 Г 3 1 : 5 ^ 4 i 3 2 4 4 8.4. На рисунке 8.5 приведены три положения кружков на стержнях. Какие из них встречаются при исполнении оптимгшьно-го алгоритма переноса башни из шести кружков со стержня А на стержень В? а) Рис. 8.5 И.. 4 5 ' 1 6 1 б) 3 I 1 1 L 2_1 -6 -П 1 1 4 1 5 в) 2 L, 1 3 i 4 6 5 8.5. На рисунке 8.6 приведены пары положений кружков на стержнях. Составьте для каждой пары программу, переводящую кружки из первого положения во второе. Постарайтесь, чтобы ваша программа была как можно короче. а) 2 , 3 ; б) 1 1 3 2 5 ! ' 4 ' 2 i з__] 4 : 5 1 I 2 ■ Рис. 8.6 Задачи без условий 205 1 3 4 8.6. Докажите, что если из некоторого положения кружки можно перевести в некоторое другое положение, то существует и программа, переводящая кружки из второго положения в первое. 8.7. а) Выполнив оптимальный алгоритм для башни из одного, двух, трех, четырех, пяти кружков, подсчитайте для каждого из этих случаев, сколько ходов делает: самый маленький кружок? второй по величине кружок? самый большой кружок? Составьте таблицу из чисел ходов каждого кружка, б) Какая тут есть закономерность? 8.8. Верно ли, что из начального положения кружков на стержнях можно за несколько ходов получить любое другое разрешенное положение кружков? 8.9. Докажите, что при исполнении оптимального алгоритма каждый нечетный ход делает самый маленький кружок. 8.10. Пусть п — целое положительное число. Тогда его можно представить в виде произведения нечетного числа и степени двойки. Например, 6 = 2*3, 12 = 4 ■ 3 = 2^ • 3 и т. д. Если число п нечетное, то степень двойки будет просто нулевая: 5 = 2° • 5. Вот начало натурального ряда при таком разложении: 2“ • 1 2* • 1 2” • 3 2^ • 1 2° • 5 2‘ * 3 2® • 7 2^ • 1 ... Забудем теперь про нечетный сомножитель и выпишем только показатель степени двойки в каждом числе. Получится последовательность целых чисел: 0102010301020104... Прибавим для удобства по единичке к каждому члену этой последовательности: 1213121412131215... а) Придумайте простое правило образования этой последовательности. Докажите, что ваше правило верное, б) Запишем номера кружков в Ханойской башне в той последовательности, в которой они двигаются при исполнении оптимального алгоритма. Получится 1 2 1 3 1 2 1 ... Докажите, что эта последовательность совпадает с той, что была написана выше. 8.11. Докажите, что при переносе кружков по оптимальному алгоритму кружок с нечетным номером никогда не попадает на другой кружок с нечетным номером, а кружок с четным номером никогда не попадает на другой кружок с четным номером. 8.12. Какой-то безобразник надел кружки на стержень А без всякого соблюдения правил: некоторые большие кружки оказа- 206 3 АДАЧ -! И х; лись сверху, а меньшие — снизу. Докажите, что, соблюдая правила игры (кладя только меньший кружок на больший), можно вернуть кружки в правильное положение. 8.13. Та же задача, но сначала кружки были в беспорядке надеты на разные стержни. 9.1 Директор строительства в книге для ученика вводится понятие критического пути. Это самая длинная цепочка блоков, которые опираются один на другой. 9.1. Напишите программы построения каждого из зданий, изображенных на рисунке 9.1, одной бригадой; двумя бригадами; тремя бригадами. Постарайтесь, чтобы каждая из ваших программ, рассчитанная на несколько бригад, осуществляла строительство за возможно меньшее число рабочих дней. Церковь аббатства Сен-Жермен (Франция) Собор Парижской Богоматери (Франция) в) 16 15 14^ Кунсткамера (С.-Петербург) 13 12 £ 11 ло. 8 g 0 11 12 13 Н 15 16 17 18 7 19 20 1 21 22 Елагин дворец. Конюшенный корпус (С.-Петербург) * " е i ус"Овий 207 Церковь Сент-Этьен дю Мон (Франция) Малая Триумфальная арка (Париж) Рис. 9.1 Театр «Гранд-опера» (Париж) 9.2. Перерисуйте в тетрадь здания с рисунка 9.1. Выберите в каждом из этих зданий блоки, составляющие какой-нибудь критический путь, и заштрихуйте их. Предположим, что в вашем распоряжении сколько угодно бригад. Составьте программы строительства каждого из зданий за наименьшее возможное число дней. 9.3. Напишите программы строительства зданий, изображенных на рисунке 9.2: а), б) двумя бригадами, в) тремя бригадами, так чтобы ни одна из бригад ни в какой день не простаивала. Докажите, что каждая из этих программ единственна (т. е. номера блоков в строке можно менять местами, но никакой из блоков нельзя установить в другой день). 208 ЗАДАЧИ И К 9.4. Для строительства зданий был выделен участок земли с очень неровной почвой. Архитектор спроектировал здания с учетом рельефа (рис. 9.3). Напишите программы строительства каждого из зданий двумя бригадами; тремя бригадами. Постарайтесь, чтобы каждая из ваших программ требовала для выполнения как можно меньше рабочих дней. б) 12 11 10 Б Г^"гГ Задачи с условиями 10. Удвоитель/Раздвоитель При решении задач удобно вместо значения ИСТИНА писать просто букву И, а вместо значения ЛОЖЬ — букву Л. В книге для ученика описаны условия по- ложительное и четное для Раздвоителя. В задачах этого раздела мы считаем, что те же условия относятся и к Удвоителю. Справа приведена эффективная программа для Раздвоителя. Эта программа получает число о из любого числа за _ наименьшее число шагов. 10.1. Напишите для чисел 0, 12, 23, 37, 124 значения условий положительное и четное. 10.2. Придумайте несколько целых чисел, для которых условия имеют следующие значения: ПОКА положительное ДЕЛАТЬ ЕСЛИ четное ТО раздели на 2 ИНАЧЕ вычти 1 КОНЕЦ КОНЕЦ положительное четное а) ИСТИНА ИСТИНА б) ЛОЖЬ ИСТИНА в) ИСТИНА ЛОЖЬ г) ЛОЖЬ ЛОЖЬ 10.3. После выполнения некоторой команды Удвоителя условия приняли следующие значения: положительное четное ИСТИНА ЛОЖЬ а) Какая это была команда? б) Каковы будут значения условий после выполнения следующей команды? 210 ЗАДАЧНИ1 10.4. В таблице показано, как менялись значения условий после выполнения Удвоителем каждой команды некоторой программы. положительное четное ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ИСТИНА Какое число горело на экране перед началом выполнения программы? Что это была за программа, если в результате ее выполнения на экране загорелось число: а) 32; б) 60; в) 172? Какие еще числа можно получить? 10.5. В таблице показано, как менялись значения условий после выполнения Раздвоителем каждой команды некоторой программы. положительное четное ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ЛОЖЬ ИСТИНА Б. Задачи с условиями 211 Какая это была программа, если сначала на экране горело число 56? 10.6. Петя сидел и записывал значения условий в ходе выполнения некоторой программы Удвоителя. Вот что у него при этом получилось: положительное четное ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ЛОЖЬ ЛОЖЬ Может ли такое быть? 10.7. Коля сидел и записывал значения условий в ходе выполнения некоторой программы Раздвоителя. Вот что у него при этом получилось: положительное четное ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ЛОЖЬ ЛОЖЬ 10.8. Может ли такое быть? Всякое число раскладывается в произведение нечетного числа и некоторой степени числа 2 (см. задачу 8.10). Это раз- 212 ЗАДАЧНИК ложение единственно. Напишите процедуру для Раздвоите-ля, которая по любому числу вычисляет этот (максимальный) нечетный сомножитель. 10.9. Напишите процедуры для Раздвоителя, получающие число 0 из чисел 5, 17, 123, 512, 846, 1023. (Возможно, у вас будет одна процедура для всех этих чисел.) Выпишите для каждого из них, какие команды выполняются и как меняются значения условий положительное и четное в ходе выполнения вашей процедуры. Используя последовательность выполняемых Раздвоителем команд, составьте для каждого из этих чисел программу его получения Удвоителем из 0. Постарайтесь, чтобы число исполняемых команд в процедуре было как можно меньшим. 10.10. Напишите процедуры для Раздвоителя, получающие второе число из первого в следующих парах: а) 8 и 2; б) 17 и 5; в) 87 и 16; г) 116 и 57; д) 324 и 4; е) 32 и 17. Выпишите для каждой процедуры, какие команды исполняются в ходе ее выполнения и как меняются значения условий положительное и четное. Используя последовательность команд, выполняемых Раздвоителем, составьте для Удвоителя программу получения первого числа из второго для всех пар чисел. Постарайтесь, чтобы число команд, исполняемых каждой из процедур, было как можно меньшим. 11.Робот 11.1. Напишите значения всех простых условий для всех положений Робота на рисунке 11.1. А В С D - - Е F G Н Рис. 11.1 Рис. 11.2 11.2. Перерисуйте в тетрадь лабиринт, изображенный на рисунке 11.2. Расставьте в его клетках буквы А, В, С, D так, чтобы значения условий для местонахождения Робота в этих клетках соответствовали таблице: Б. Задачи с условиями А в с D сверху свободно ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ справа свободно ЛОЖЬ ложь ИСТИНА ИСТИНА снизу свободно ИСТИНА ложь ИСТИНА ИСТИНА слева свободно ЛОЖЬ ложь ИСТИНА ИСТИНА закрашена ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ Укажите все возможные решения. 11.3. Перерисуйте в тетрадь рисунок 11.3. Расставьте на нем стены и закрасьте клетки так, чтобы значения условий для местонахождения Робота в клетках А, В, С, D соответствовали таблице: т с D А ; 1 1 Рис. 11.3 А В с D сверху свободно ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ справа свободно ЛОЖЬ ложь ЛОЖЬ ЛОЖЬ снизу свободно ИСТИНА ложь ИСТИНА ИСТИНА слева свободно ЛОЖЬ ложь ИСТИНА ЛОЖЬ закрашена ЛОЖЬ ИСТИНА ИСТИНА ложь 11.4. На рисунке 11.4 показано положение клеток А, В, С, D, Е на поле. Можно ли расставить на этом поле стены так, чтобы условия имели следующие значения? а) А В С Е D Рис. 1 1.4 А в с D Е сверху свободно ИСТИНА ЛОЖЬ ИСТИНА ложь ИСТИНА справа свободно ЛОЖЬ ложь ложь ложь ЛОЖЬ снизу свободно ИСТИНА ложь ИСТИНА ИСТИНА ИСТИНА слева свободно ЛОЖЬ ложь ИСТИНА ложь ИСТИНА закрашена ЛОЖЬ ИСТИНА ложь ИСТИНА ЛОЖЬ 214 ЗАДАЧНИК б) А В С D Е сверху свободно ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА справа свободно ЛОЖЬ ЛОЖЬ ЛОЖЬ ЛОЖЬ ЛОЖЬ снизу свободно ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА слева свободно ЛОЖЬ ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА закрашена ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ А В с D Е сверху свободно ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ справа свободно ЛОЖЬ ЛОЖЬ ЛОЖЬ ЛОЖЬ ложь снизу свободно ЛОЖЬ ложь ИСТИНА ИСТИНА ИСТИНА слева свободно ЛОЖЬ ложь ЛОЖЬ ЛОЖЬ ИСТИНА закрашена ЛОЖЬ ИСТИНА ложь ЛОЖЬ ЛОЖЬ 11.5. Робот выполнил команду влево. Истинно или ложно условие справа свободно? 11.6. В таблице указаны команды, которые выполнил Робот, и значения условий после выполнения каждой команды. Некоторые клетки не заполнены, а) Нарисуйте путь Робота по полю и расставьте стенки, о положении которых вы знаете из таблицы: слева свободно сверху свободно справа свободно снизу свободно вверх ИСТИНА ЛОЖЬ ЛОЖЬ влево ЛОЖЬ ЛОЖЬ вниз ИСТИНА ЛОЖЬ вниз ЛОЖЬ ложь влево ЛОЖЬ ИСТИНА вверх ЛОЖЬ вверх ЛОЖЬ Б. Задачи с условиями 215 Продолжение слева свободно сверху свободно справа свободно снизу свободно вверх ИСТИНА ЛОЖЬ вправо ИСТИНА вправо ИСТИНА вправо ЛОЖЬ ЛОЖЬ вниз ИСТИНА вниз ИСТИНА ложь влево ИСТИНА б) Перепишите таблицу в тетрадь, заполнив свободные клетки. 11.7. На рисунке 11.5 изображен лабиринт. Начальное положение Робота помечено буквой А, конечное — буквой D. Рис. 11.5 D А В таблицах приведено состояние условий Робота после выполнения каждой команды нескольких программ. а) слева свободно сверху свободно справа свободно снизу свободно А ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА D ИСТИНА ЛОЖЬ ЛОЖЬ ИСТИНА 216 ЗАДАЧНИК б) слева свободно сверху свободно справа свободно снизу свободно А ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА D ИСТИНА ЛОЖЬ ЛОЖЬ ИСТИНА в) слева свободно сверху свободно справа свободно снизу свободно А ИСТИНА ИСТИНА ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА ложь ИСТИНА ИСТИНА D ИСТИНА ложь ЛОЖЬ ИСТИНА Напишите для всех случаев, какую программу выполнял Робот. 11.8. На рисунке 11.6 изображен лабиринт. Составьте таблицу значений следующих сложных условий для каждой из клеток А, В, С, D, Е, F, G, Н: а) сверху свободно И справа свободно; б) снизу свободно И закрашена; в) справа свободно ИЛИ снизу свободно; г) НЕ закрашена; д) сверху свободно ИЛИ (НЕ слева свободно); е) (НЕ сверху свободно) И (НЕ закрашена); ж) НЕ (снизу свободно И закрашена); з) (НЕ снизу свободно) ИЛИ (НЕ закрашена). А В С D Е F L Н Рис. П.6 Б. Задачи с условиями 217 11.9. Перерисуйте в тетрадь лабиринт с рисунка 11.2 и расставьте в его клетках буквы А, В, С, D так, чтобы значения сложных условий в этих клетках совпадали с приведенными в следующей таблице: слева свободно И справа свободно (НЕ сверху свободно) И (НЕ закрашена) снизу свободно ИЛИ (НЕ слева свободно) А ЛОЖЬ ЛОЖЬ ИСТИНА В ЛОЖЬ ИСТИНА ИСТИНА С ЛОЖЬ ЛОЖЬ ЛОЖЬ D ИСТИНА ЛОЖЬ ИСТИНА Укажите все возможные решения. 11.10. На рисунке 11.7 изображен лабиринт. Придумайте сложные условия со следующими значениями в клетках А, В, С, D, Е: А В С D Е F G Н Рис. 11.7 А в с D Е а) ИСТИНА ЛОЖЬ ИСТИНА ИСТИНА ИСТИНА б) ЛОЖЬ ложь ложь ЛОЖЬ ИСТИНА в) ЛОЖЬ ложь ИСТИНА ИСТИНА ЛОЖЬ г) ЛОЖЬ ложь ложь ИСТИНА ЛОЖЬ Д) ЛОЖЬ ИСТИНА ИСТИНА ЛОЖЬ ИСТИНА 11.11. Робот стоит в горизонтальном коридоре шириной в одну клетку, ограниченном справа. Составьте процедуру, выполнив которую Робот закрасит все клетки справа от себя. 11.12. Робот стоит в углу прямоугольника, внутри которого стен нет. Составьте процедуру, переводящую его в противоположный угол прямоугольника. 11.13. Роботу разрешается использовать только одну процедуру движения — вправо вниз (см. справа). Больше никакие команды движения использовать нельзя. Робот стоит на поле, где-то внизу — горизонтальная стена, а справа — вертикальная ПРОЦ вправо вниз НАЧАЛО шаг вниз шаг вправо КОНЕЦ 218 Б. ЗАДАЧИ С УСЛОВИЯМИ Рис. 11.8 стена. Напишите процедуру, выполняя которую Робот дойдет до стены по диагонали (неизвестно, на какую стену Робот наткнется сначала). 11.14. Робот стоит в прямоугольнике, внутри которого стен нет. Один из горизонтальных рядов прямоугольника закрашен, за исключением одной клетки (рис. 11.8). Составьте процедуру, выполнив которую Робот остановится в этой клетке. 11.15. Робот стоит в правом конце ограниченного коридора шириной в одну клетку. Составьте процедуру, выполнив которую Робот закрасит клетки коридора в шахматном порядке. Клетка, где стоит Робот, должна быть закрашена. 11.16. Робот стоит в левом конце ограниченного коридора. Составьте процедуру, выполнив которую он закрасит клетки коридора через две на третью. Клетка, где стоит Робот, должна быть закрашена (рис. 11.9). Рис. 11.9 11.17. Робот стоит в прямоугольнике, внутри которого стен нет. Составьте процедуру, выполнив которую он закрасит клетки прямоугольника в шахматном порядке. 11.18. Робот находится в нижней части прямоугольника, разделенного горизонтальной стеной, в которой есть два отверстия шириной в одну клетку, расположенные не у стен прямоугольника (рис. 11.10). Составьте программу, выполняя которую Робот перейдет в верхнюю часть прямоугольника через левое отверстие, а вернется в нижнюю через правое. 11.19. Робот находится внутри горизонтального коридора ширины 1 около левой стенки. Коридор имеет несколько ответвлений вверх. Два из них соединены между собой другим Рис. 11.10 Рис. 11.11 t>. о с с условиями 219 горизонтальным коридором, а остальные ответвления — тупики (рис. 11.11). Напишите программу, выполняя которую Робот закрасит все клетки соединенных ответвлений. 11.20. Стены внутри замкнутого прямоугольника образуют только левые верхние углы и не примыкают к стенам прямоугольника (рис. 11.12). Переведите Робота в верхний левый угол прямоугольника. 11.21. Робот стоит у стены, ограничивающ,ей линейно-выпуклый многоугольник, т. е. такой многоугольник, пересечение которого с любой вертикальной и горизонтальной прямой есть отрезок (рис. 11.13). Рис. 11.12 Рис. 11.13 Напишите процедуру, выполняя которую Робот закрасит полоску ширины 1 вокруг многоугольника. 11.22. Для Робота написаны две процедуры, которые называются ходи так и ходи сяк. Можно ли, не зная этих процедур, утверждать, что программы ходи так ходи сяк и ходи сяк ходи так переводят Робота в одну и ту же клетку, если начальные клетки совпадали? Разберите два случая: а) на поле нет стенок; б) на поле могут быть стены. 11.23. Напишите программу для Робота, которая перемеш;ает его в соседнюю клетку при условии, что клетка Робота не отделена стеной хотя бы от одной из соседних клеток. 11.24. Робот находится в клетке А лабиринта, фрагмент которого изображен на рисунке 11.14. Известно, что существует путь по лабиринту из клетки А в клетку В. Напишите программу, в процессе выполнения которой Робот побывает в клетке В. Рис. 11.14 I I I . T------------------- . . I 6 ! I о nf f rfWflO . I*tivr«u%r* У Сложные задачи (проекты) 12. Удвоитель: построение оптимального алгоритма в этом разделе мы не пользуемся процедурами и циклами. Оптимальным алгоритмом здесь, как и везде далее, мы называем алгоритм, требующий наименьшего числа действий. Сложная задача, которую мы будем решать, выглядит так: На экране Удвоителя горит целое положительное число а. Написать программу получения числа Ь из числа а за наименьшее число шагов. Эту задачу мы разобьем на несколько более простых, решение которых постепенно подведет нас к решению сложной задачи. Ясно, что указанная программа существует, только если Ь > а (см. задачу 2.6). Для этого случая мы и будем ее строить. 12.1. Докажите, что если Ь < 2а, то существует единственная программа получения Ь из а. Какая это программа? 12.2. Придумайте оптимальные алгоритмы получения из числа а чисел: а) 2а; б) 2а -Ь 1; в) 2а -I- 2; г) 2а -f 3; д) 2а + 4. Докажите, что они действительно оптимальные. 12.3. Вот программа получения числа 2а + 2 из числа а (I). Является ли она оптимальной? Как ее можно улучшить? 12.4. Вот программа получения числа 51 из числа 5 (2). Является ли она оптимальной? Как ее можно улучшить? Подсказка: обратите внимание на группу подряд идущих команд и воспользуйтесь задачей 12.3. 1 ' I 1) умножь на 2 ' прибавь 1 ' f прибавь 1 2) ; умножь на 2 I умножь на 2 умножь на 2 прибавь 1 прибавь 1 умножь на 2 } прибавь 1 прибавь 1 прибавь 1 прибавь 1 прибавь 1 I прибавь 1 , прибавь 1 I прибавь 1 I, прибавь 1 прибавь 1 I прибавь 1 В. Сложные задачи (проекты) 221 умножь на 2 прибавь 1 прибавь 1 12.5. Докажите, что программа не может быть оптимальной, если в ней встречается группа подряд идущих команд __ Сформулируем алгоритм улучшения программы: • Если первыми а командами в программе получения числа Ь из числа а являются команды прибавь 1, то их можно заменить на команду умножь на 2. • Если в программе есть группа подряд идущих команд 1, то программу можно улучшить, заменив эту группу команд на группу 2. 1) умножь на 2 - прибавь 1 прибавь 1 2) прибавь 1 умножь на 2 Алгоритм построения оптимальной программы: Пусть у нас есть какая-нибудь программа получения числа Ь из числа а. Будем улучшать ее с помощью алгоритма улучшения до тех пор, пока не придем к программе, которую нельзя улучшить. Эта программа и будет оптимальной. Построим оптимальную программу получения числа 10 из числа 3. Сначала возьмем программу, состоящую из семи команд прибавь 1. К ней можно применить первое правило улучшения и заменить первые три команды прибавь 1 на команду умножь на 2, а затем прибавь 1 прибавь 1 умножь на 2 Последнюю программу улучшить уже нельзя. 12.6. Воспользовавшись алгоритмом построения оптимальной программы, постройте оптимальные программы получения: а) числа 13 из числа 2; б) числа 51 из числа 5; в) числа 59 из числа 5; г) числа 63 из числа 7; д) числа 64 из числа 1; е) числа 47 из числа 1; ж) числа 31 из числа 1. 12.7. Докажите, что неулучшаемая программа получения числа Ь из числа а выглядит так: сначала имеется несколько команд прибавь 1, причем их число меньше а, затем идут команды умножь на 2 и прибавь 1, причем две команды прибавь 1 не могут стоять рядом. 222 ЗАДАЧНИК 12.8. Пусть b > 2а. Докажите, что: а) если Ь нечетное, то последней командой в любой программе будет команда прибавь 1; б) если Ь четное, то последней командой в неулучшаемой программе будет команда умножь на 2. 12.9. Воспользовавшись результатами двух предыдущ;их задач, докажите, что для любой пары целых положительных чисел а и Ь {а < Ь) существует единственная неулучшаемая программа получения & из а. 12.10. Докажите, что применение алгоритма построения оптимальной программы к любой программе получения 6 из а дает один и тот же результат. 12.11. Воспользовавшись результатом предыдущей задачи, докажите, что неулучшаемая программа является оптимальной. 12.12. Как нужно строить оптимальную программу получения произвольного числа Ь из числа О? 12.13. Сформулируйте алгоритм построения оптимальной программы получения числа а из числа Ь для Раздвоителя, не использующей проверки условий. Докажите правильность вашего алгоритма. 12.14. Докажите, что при исполнении эффективной программы (см. раздел 10 Задачника) и оптимальной программы, построенной алгоритмом предыдущей задачи, Раздвоитель выполняет одни и те же действия. Оставим теперь в алгоритме построения оптимальной программы только второе преобразование: группу команд умножь на 2 прибавь 1 прибавь 1 можно заменить на группу прибавь 1 умножь на 2 Будем говорить, что две программы Удвоителя эквивалентны, если применение их к одному и тому же числу дает один и тот же результат. 12.15. Докажите, что после проведения второго преобразования новая программа будет эквивалентна старой. Рассмотрим какую-нибудь программу и все программы, которые ей эквивалентны. 12.16. Докажите, что среди таких программ есть только одна неулучшаемая. 12.17. Докажите, что в двух эквивалентных программах содержится одинаковое число команд умножь на 2. 12.18. Докажите, что любую программу, эквивалентную данной, можно получить из нее, последовательно применяя В. Сяож^^- е задачи ('проекты) 223 второе преобразование или, наоборот, заменяя группу команд прибавь 1 умножь на 2 на группу команд умножь на 2 прибавь 1 прибавь 1 Введем еще одного Исполнителя — Утроитель, — работающего с числами на экране. Утроитель имеет две команды: прибавь 1 и умножь на 3. По команде прибавь 1 увеличивает число на экране на 1, а по команде умножь на 3 увеличивает число на экране втрое. 12.19. Составьте программы получения: а) числа 5 из числа 1; б) числа 17 из числа 1; в) числа 123 из числа 1; г) числа 27 из числа 1; д) числа 26 из числа 1; е) числа 80 из числа 1; ж) числа 17 из числа 5; з) числа 80 из числа 8; и) числа 81 из числа 9; к) числа 81 из числа 8. Постарайтесь, чтобы ваши программы использовали как можно меньше команд. 12.20. Докажите, что если Ъ < За, то существует единственная программа получения Ь из а. Какая? 12.21. Придумайте оптимальные алгоритмы получения из числа а чисел: а) За; б) За + 1; в) За -I- 2; г) За + 3; д) За -t- 4. Докажите, что они оптимальные. _______ 12.22. Вот программа получения числа За Ч- 3 из числа а (см. справа). Является ли она оптимальной? Как ее можно улучшить? 12.23. Сформулируйте алгоритм улучшения программы для Утроителя. 12.24. Какие программы для Утроителя являются неулучшаемыми? 12.25. Как выглядит оптимальная программа получения числа Ь из числа а для Утроителя? 12.26. Введите нового Исполнителя — Растроитель. Какие у него должны быть команды и условия? Напишите эффективную программу получения числа 0 из любого числа. 1 умножь на 3 прибавь 1 прибавь 1 прибавь 1 13. Водолей: построение универсального алгоритма Цель этого раздела — решить общую задачу. У Водолея есть два сосуда А и В вместимостью а и Ь литров. Перед выполнением программы оба сосуда пустые. Какое количество литров он может отмерить? Как отмерить 1 литр? При решении задач из раздела 1 части А вам, вероятно, приходилось выливать всю воду из сосуда, как только он наполнялся. 224 ЗАДАЧНИК ЕСЛИ А полный ТО вылей из А КОНЕЦ Поэтому для удобства работы с Водолеем можно ввести условия: <сосуд> полный Вместо <сосуд> должно быть имя сосуда, скажем, А или В. Вот пример программы (см. справа). Условие А полный истинно, если сосуд А наполнен до краев, и ложно в противном случае. Будем в дальнейшем считать для определенности, что а < Ь. 13.1. Процедура до краев описана следующим образом (см. справа). Каков результат ее выполнения в случае, если: а) Ь = 8, а = 5; б) Ь = 9, а = 6; в) Ь = 8, а = 2; г) Ь = 17, а = 3; р) Ь = 14, а = 9; е) Ь = 13, а = 11; ж) Ь = 36, а = 20; з) Ь = 144, а = 81? 13.2. Каков результат выполнения программы а в тех же случаях? 13.3. Пусть а = 5, Ь = 8, как в задаче 13.1а. На рисунке 13.1 пять точек расположены на окружности в вершинах правильного пятиугольника. В этих точках против часовой стрелки стоят числа от о до 4. Рассмотрим программу б. ПРОЦ до краев НАЧАЛО ПОКА НЕ (В полный) наполни А перелей из А в В КОНЕЦ КОНЕЦ а) ПОВТОРИТЬ 2 РАЗ б) ПОВТОРИТЬ 5 РАЗ до краев до краев вылей из В вылей из В перелей из А в В перелей из А в В КОНЕЦ КОНЕЦ После первого выполнения цикла в сосуде В оказывается 2 литра воды. Нарисуем стрелочку от 0 к 2 (рис. 13.2). После второго выполнения цикла в сосуде В оказывается 4 литра воды. Нарисуем стрелочку от 2 к 4. Нарисуйте стрелочки, соответствующие третьему, четвертому и пятому выполнениям цикла. 1. 2. 3* Рис. 13.1 Рис. 13.2 1. В. Сложные задачи (проекты) 225 ПОВТОРИТЬ а РАЗ до краев вылей из В перелей из А в В КОНЕЦ 13.4. Для каждого из пунктов б—з задачи 13.1 поставьте точку в каждой верпиине правильного а-угольника (всего а точек). Напишите в этих точках против часовой стрелки числа от О до а - 1. Отметьте точки, соответ- ствующ;ие числу литров в сосуде В после каждого выполнения цикла. Соедините эти точки стрелками в той последовательности, в которой они появляются. Какие фигуры у вас получились? 13.5. Для случаев а—з задачи 13.1 напишите программу рисования Черепахой фигур, полученных в предыдущей задаче. 13.6. а) Для каких из случаев а—з задачи 13.1 построенная в задаче 13.4 фигура не проходит через точку 1? б) Для каких из этих случаев она проходит не через все точки? в) Для каких из этих случаев фигура проходит несколько раз? г) Сколько раз она проходит в каждом из случаев а—з? 13.7. Пусть числа а а Ь взаимно просты (не имеют общих делителей, больших 1). Докажите, что построенная в предыдущей задаче фигура в этом случае проходит через все точки. Выведите отсюда, что для взаимно простых а и Ь Водолей может отмерить: а) 1 литр; б) любое количество литров, меньшее Ь. 13.8. Докажите, что для произвольных а и Ь фигура, построенная в задаче 13.4, проходит через все точки, в которых стоят числа, кратные НОД(а, Ь). 13.9. Как будет работать программа из задачи 13.4, если а > Ь? Какие при этом получатся фигуры? Нарисуйте их для случаев а—е из задачи 13.1 при условии, что значения а и Ь поменялись местами. 13.10. Пусть по-прежнему а < Ь. Для каждого из пунктов а—е задачи 13.1 поставьте точку в каждой вершине правильного Ь-уголь-ника (всего Ъ точек). Напишите в этих точках против часовой стрелки числа от О до & - 1. Отметьте точки, соответствующие числу литров в сосуде В, после каждого изменения количества воды в этом сосуде при выполнении программы. Соедините эти точки стрелками в той последовательности, в которой они появляются. Какие фигуры у вас получились? 13.11. Напишите для Черепахи программы рисования фигур, которые получаются в предыдущей задаче. ПОВТОРИТЬ а РАЗ до краев вылей из В перелей из А в В КОНЕЦ 226 ЗАДАЧНИК 13.12. Докажите, что Водолей может отмерить любое количество воды, кратное НОД(а, Ь) и не превосходящее наибольшее из чисел а VI Ь. 13.13. Добавим в систему команд Водолея условие в <сосуде> <число> литров Например, условие в А 5 литров истинно, если в А действительно 5 литров, и ложно в противном случае. Используя это условие, в каждом из случаев а—е задачи 13.1 напишите программу, выполнив которую Водолей отмерит наименьшее возможное число литров. 13.14. Решите предыдущую задачу, если условие <сосуд> полный заменили на условие <сосуд> пустой. 13.15. Сформулируйте и решите теперь задачи, аналогичные задачам 13.1—13.8, для программы (см. справа). Что будет происходить в программе, если в процедуре до дна команды вылей из А и перелей из В в А поменять местами? ПОВТОРИТЬ а РАЗ наполни В перелей из В в А до дна КОНЕЦ 14. Рекурсия. Сложные задачи для Робота в этом разделе: • начальное положение Робота; О конечное положение Робота. 14.1. Робот стоит в бесконечном горизонтальном коридоре ширины 1, ограниченном сверху и снизу стенами. Одна из клеток справа от Робота закрашена. Робот должен дойти до закрашенной клетки, пройти ее и остановиться с другой стороны от закрашенной клетки на таком же расстоянии от нее, т. е. оказаться в клетке, симметричной исходной относительно закрашенной (рис. 14.1). Напишите соответствующую программу. 14.2. Как будет работать процедура из решения предыдущей задачи, если справа от Робота: а) нет ни одной закрашенной клетки; б) две закрашенные клетки? Робот стоит здесь тг р Робот должен оказаться здесь Рис. 14.1 В. Сложные задачи (проекты) 14.3. Робот стоит в горизонтальном коридоре ширины 1, где-то слева от него закрашенная клетка. Напишите процедуру, выполняя которую Робот дойдет до закрашенной клетки и вернется в начальное положение. 14.4. Робот стоит в горизонтальном коридоре ширины 1, где-то слева от него стена. Напишите процедуру, выполняя которую Робот дойдет до стены и вернется в начальное положение. Некоторые задачи, которые можно (и нужно) решать без использования рекурсии, допускают и рекурсивное решение. Приведем два таких примера. 14.5. Напишите рекурсивную программу, подводящую Робота к горизонтальной стене сверху от него. 14.6. Напишите программу для Эффективного Раздвоителя, вызывающую рекурсивную процедуру. Иногда рекурсию можно заменить закрашиванием клеток. 14.7. Без применения рекурсии решите задачи: а) 14.3; б) 14.4 при условии, что Робот может по дороге закрашивать клетки. 14.8. Робот стоит у горизонтальной стены снизу от нее, где-то слева от него стена кончает- " “ q ся. Напишите процедуру, выполняя которую Робот обойдет стену и окажется в клетке рядом со стеной над Рис. 14.2 своим начальным положением (рис. 14.2). 14.9. Робот стоит ниже горизонтальной стены, где-то слева от него стена кончается. Напишите процедуру, выполняя которую Робот обойдет стену и окажется в клетке, симметричной его начальному положению относительно стены (рис. 14.3). 14.10. Робот стоит в бесконечном го- Рис. 14.3 ризонтальном коридоре ширины 1, сверху и снизу — стены. Одна из клеток справа от Робота закрашена. Робот должен дойти до закрашенной клетки, пройти ее и остановиться с другой стороны от закрашенной клетки на расстоянии, вдвое большем, чем вначале. о - - - • 228 ЗАДАЧНИК 14.11. На поле Робота стен нет. Справа и сверху от Робота расположена диагональ из закрашенных клеток. Напишите процедуру, выполнив которую Робот окажется в клетке, симметричной исходной относительно этой диагонали (рис. 14.4). 14.12. Роботу разрешается использовать только две процедуры движения — вправо вниз и вправо вверх, описанные следу-ющ;им образом: ПРОЦ вправо вниз ПРОЦ вправо вверх НАЧАЛО НАЧАЛО шаг вниз шаг вверх шаг вправо шаг вправо КОНЕЦ КОНЕЦ Больше никакие команды движения использовать нельзя. Робот стоит на поле, где-то внизу находится горизонтальная стена. Напишите процедуру, выполняя которую Робот дойдет до стены по диагонали, «отразится» от стены и, пройдя по диагонали, остановится на таком же расстоянии от стены, что и в исходной позиции (рис. 14.5). О • • О Рис. 14.4 Рис. 14.5 14.13. Робот находится на закрашенной клетке в горизонтальном коридоре, других закрашенных клеток нет. Коридор с одной стороны ограничен, но неизвестно — справа или слева. Напишите процедуру, в которой Робот ищет вертикальную стену и останавливается возле нее. а) Закрашивать дополнительные клетки не разрешается, б) Разрешается закрашивать клетки. 14.14. Где-то на поле находится бесконечная стена, тянущаяся в одном (но неизвестном) направлении. Робот стоит в центре креста из закрашенных клеток шириной в одну клетку и В. Сложные задачи (проекты) 229 Путь Робота отмечен штриховой линией L,._ Т 4J- начинает искать стену, двигаясь по спирали (рис. 14.6). Напишите процедуру, выполняя которую Робот в конце концов остановится у стены, а) Закрашивать дополнительные клетки не разрешается, б) Разрешается закрашивать клетки, но нельзя применять рекуфсию. 14.15. Робот находится в замкнутом коридоре шириной 1 на закрашенной клетке (рис. 14.7). Составьте программу, выполняя которую Робот пройдет по всему коридору и вернется на исходное место. 14.16. Стены внутри прямоугольника расположены так, что у каждой клетки две стороны свободны, а две закрыты стенами, причем Робот может дойти до любой клетки (рис. 14.8). Составьте программу, закрашивающую все клетки такого лабиринта. г 1 J JJ Рис. 14.6 Рис. 14.7 Рис. 14.8 14.17. Робот стоит в лабиринте, причем он может дойти лишь до конечного числа клеток. Напишите программу, выполняя которую Робот закрасит все доступные ему клетки. 15. Ханойские башни Этот раздел посвящен доказательству правильности дзэн-алгоритма. В головоломке Ханойские башни в каждом ходе «участвуют» два стержня: тот, с которого мы берем диск, и тот, на который мы диск кладем. Третий стержень никак не участвует в ходе. С другой сторо- 230 ЗАДАЧНИК ны, если мы знаем, какой из стержней не участвует в ходе, то нам известен и сам ход: из оставшихся двух стержней мы выбираем тот, у которого верхний диск меньше, снимаем этот диск и переносим его на второй стержень. Поэтому Исполнитель Монах с системой команд перенеси не трогая А перенеси не трогая В перенеси не трогая С тоже может выполнить программу переноса дисков. Посмотрим, как выглядит такая программа для простого случая двух дисков. Если на первом ходу мы не трогаем стержень В, то получается перенеси не трогая В перенеси не трогая С перенеси не трогая А Эта программа переносит башню со стержня А на стержень В. 15.1. Запишите в новой системе команд известный вам алгоритм переноса башни (раздел 8) из: а) трех дисков; б) четырех дисков. 15.2. Мы переносим башню со стержня А на стержень В. Какой должна быть первая команда в программе? Как это зависит от числа дисков в башне? Если вы правильно решили задачу 15.1, то увидели, что алгоритм переноса оказывается очень простым. Дзэн-алгоритм переноса Ханойской башни: нетронутые стержни меняются по кругу — ВСАВСАВС А... или СВАСВАСВ А... 15.3. Докажите, что оптимальный алгоритм переноса Ханойской башни со стержня А на стержень В записывается для четного числа дисков в башне в виде а, для нечетного числа дисков в башне в виде б. а) перенеси перенеси перенеси перенеси перенеси перенеси перенеси перенеси перенеси не трогая не трогая не трогая не трогая не трогая не трогая не трогая не трогая не трогая В С А В С А В С А б) перенеси перенеси перенеси перенеси перенеси перенеси перенеси перенеси перенеси не трогая С не трогая В не трогая А не трогая С не трогая В не трогая А не трогая С не трогая В не трогая А В. Сложные задачи (проекты) 231 15.4. Сколько раз должен быть повторен цикл из трех команд при записи программы? Запишите с помощью конструкции цикла программу переноса башни из: а) трех дисков; б) четырех дисков; в) пяти дисков; г) шести дисков. Подсказка: воспользуйтесь решением задачи 8.7. 16. Кривые дракона Красивгш ломаная, изображенная на рисунке 16.1, называется кривой дракона порвдка 10. Наша главная задача в этом разделе — научиться писать для Черепахи простые программы рисования этой и похожих кривых. l: р lP ъ LJ □ Г □ Ri № и Z d:? □ п_ l: :Л □ ъ R Ъ Рис. 16.1 232 ЗАДАЧНИК РгГ сР □1 -в с □ □ гу: Ъ R:i Jb ь л о На рисунке 16.2 приведены кривые дракона порядка О, 1, 2, 3, 4, 5. J Ь ^ О 1 Рис. 16.2 Мы начинаем рисовать каждую из таких кривых всегда в одной точке, называемой головой дракона, и идем из этой точки вправо. Конечную точку кривой назовем хвостом дракона. На рисунке хвост отмечен жирной точкой. Кривая дракона порядка п -I- 1 получается из кривой дракона порядка п следующим образом: нужно нарисовать кривую дракона порядка п и затем повернуть ее на 90 градусов по часовой стрелке относительно хвоста. 16.1. Сколько звеньев в кривой дракона порядка: а) 2; б) 3; в) 5; г) 10; д) п? 16.2. Напишите процедуры рисования кривых дракона порядка: а) 3; б) 4; в) 5; г) 6. Считайте длину отрезка ломаной равной 5. Поворачивайте Черепаху только командами вправо (90) и влево (90). 16.3. Напомним, что Ленивая Черепаха выполняет только команды поворота, отдаваемые обычной Черепахе. Обозначим команду поворота вправо (90) буквой R, а команду поворота влево (90) буквой L (сокращение английских слов Right и Left). Для кривой дракона порядка 2 Ленивая Черепаха выполнит команды LLR, а для кривой дракона порядка 3 — команды LLRLLRR. Как будут выглядеть команды для Ленивой Черепахи при рисовании кривых дракона порядков: а) 4; б) 5? Какая тут есть закономерность? 16.4. Решите задачу 16.2, считая, что кривая дракона рисуется от хвоста к голове. Для каждого из решений выпишите последовательность команд для Ленивой Черепахи. Сравните получающиеся последовательности с последовательностями из предыдущей задачи. ^ Сложные задачи (проекты) 233 16.5. 16.6. 16.7. Пусть процедура КДг4 рисует кривую дракона четвертого порядка, начиная с головы, а процедура КДх4 рисует ту же кривую, но начиная с хвоста. Используя эти две процедуры, напишите две процедуры КДг5 и КДх5, рисующие кривую дракона пятого порядка от головы к хвосту и от хвоста к голове. Используя решения задач 16.4 и 16.5, научите Черепаху рисовать все кривые дракона до десятого порядка. Научите Черепаху рисовать изображенные на рисунке 16.3 кривые дракона с згпсругленными углами (назовем их гладкими кривьпни дракона) для кривых дракона порядка 2, 3, 4, 5. J Ь ^ 12 3 4 Рис. 16.3 16.8. Четыре Черепахи начали из одной точки рисовать вправо, вверх, влево и вниз гладкие кривые дракона одного и того же порядка. В каких точках пересекаются эти кривые? 16.9. Определяя стандартную кривую дракона порядка п -(- 1, мы поворачивали кривую дракона порядка п на 90 градусов по часовой стрелке. Какая кривая получится, если мы будем поворачивать ее против часовой стрелки на 90 градусов? Научите Черепаху рисовать такие кривые разного порядка. 16.10. Какая кривая получится, если мы при переходе от кривой порядка п к кривой порядка п -Ь 1 будем поочередно выполнять повороты вправо и влево на 90 градусов? Научите Черепаху рисовать такие кривые до десятого порядка. 16.11. Рассмотрим последовательность LLRLRLRRL. Будем строить по этой последовательности нестандартную кривую дракона десятого порядка, придерживаясь следующего правила. Кривую первого порядка построим из кривой нулевого порядка, как обычно, с поворотом влево (первая буква в последовательности — буква L). Кривую второго порядка — из кривой первого порядка поворотом влево (вторая буква в последовательности тоже L). Кривую третьего порядка — из кривой второго порядка, но с поворотом вправо (третья 234 ЗАДАЧНИК буква в последовательности — буква R) и т. д. Напишите для Черепахи программу построения такой нестандартной кривой дракона. Директор строительства: построение универсального алгоритма в начале этого раздела предложен цикл задач, решение которых в совокупности дает решение следуюш;ей общей задачи: Пусть на чертеже изображено какое-либо здание. Найти минимальное число дней, за которое это здание может быть построено, если в распоряжении Директора имеется неограниченное количество строительных бригад. Рассмотрим только те блоки, которые опираются на основу (и не опираются на другие блоки). Они составляют первый этаж здания. Пометим их цифрой 1 в кружочке (рис. 17.1). Второй этаж здания образуют блоки, которые опираются только на основу и блоки первого этажа. Конечно, блоки первого этажа не относятся ко второму этажу. На рисунке 17.2 блоки второго этажа помечены цифрой 2 в кружочке. Третий этаж состоит из блоков, опирающихся только на основу и блоки первого и второго этажей. Блоки третьего этажа помечены цифрой 3 (рис, 17.3). В. Сложные задачи (проекты) 235 Понятно, какие блоки составляют четвертый и пятый этажи (рис. 17.4). Обратите внимание на то, что блоки, относящиеся к одному и тому же этажу, могут находиться на разной высоте: блоки второго этажа могут лежать выше блоков третьего этажа и т. д. 17.1. Перерисуйте в тетрадь чертежи задачи 9.1. Расставьте на блоках номера этажей. 17.2. Докажите, что никакое здание нельзя построить быстрее, чем за число дней, равных числу этажей в нем, сколько бы бригад ни участвовало в строительстве. 17.3. Докажите, что, имея в своем распоряжении достаточное количество бригад. Директор может построить любое здание за столько дней, сколько этажей в этом здании. 17.4. Воспользовавшись решением задачи 17.1, напишите программы построения зданий задачи 9.1 за наименьшее число дней, считая, что в вашем распоряжении сколько угодно бригад. 17.5. Докажите, что число блоков в любом критическом пути совпадает с числом этажей в здании. Теперь нам предстоит решить еще одну сложную задачу. Для решения мы снова разобьем ее на несколько простых задач. Пусть на чертеже изображено какое-либо здание и у Директора в распоряжении имеется несколько бригад. Как быстрее всего построить это здание? Отличие этой задачи от рассмотренной в начале раздела состоит в том, что здесь число бригад задано заранее: у Директора может быть две бригады или три и т. д. Посмотрим снова на рисунок здания. Нам на помощь опять приходит уже несколько раз выручавшая нас идея: начать с конца. Будем обозначать цифрами в квадратике этажи здания, считая сверху. Первый «этаж* составляют блоки, на которые не опирается ни один другой блок (рис. 17.5). На блоки второго этажа опираются только блоки первого этажа и т. д. (рис. 17.6). 236 ЗАДАЧНИК Обратите внимание на то, что этажи, обозначенные цифрами в квадратиках, совсем не похожи на этажи, обозначенные цифрами в кружочках: пятый этаж в квадратиках вовсе не совпадает с первым этажом в кружочках. 17.6. Еще раз перерисуйте здания задачи 9.1 и расставьте на своем чертеже этажи в квадратиках сверху вниз. 17.7. Докажите, что в любом здании число этажей в квадратиках равно числу этажей в кружочках. А теперь мы можем сформулировать алгоритм самой быстрой постройки здания заданным числом бригад: • Рассмотрим все блоки первого (в кружочках) этажа. Выберем из них столько блоков, сколько у нас бригад. При этом будем выбирать блоки, в которых стоят самые большие числа в квадратиках. Если число блоков на первом этаже не превосходит числа бригад, то мы возьмем все блоки первого этажа и установим их в первый день. • Во второй и все последующие дни мы поступим точно так же, причем каждый раз будем иметь дело только с блоками, опирающимися на уже поставленные блоки (и на основу). Посмотрим, как работает этот алгоритм для двух бригад. Воспроизведем еще раз последний рисунок, но, помимо этажей в квадратиках, пометим номерами еще и блоки (рис. 17.7). ЛИэ П27 Г“ 8 6| 1 2 @1 3 Р5| Рис. 17.7 День 1-й. На первом, самом нижнем этаже — четыре блока с номерами 1, 2, 3 и 4. Номера их этажей в квадратиках 3, 3, 4 и 5. Согласно алгоритму мы должны взять два блока с самыми большими номерами этажей в квадратиках. Это блоки 4 и 3, их этажи в квадратиках — 5 и 4. Поэтому в первый день команды будут установи (3); установи (4) задачи (проекты) 237 День 2-й. После того как блоки 3 и 4 установлены, есть три блока, которые опираются только на землю и на блоки 3 и 4. Это блоки 1, 2 и 5. Номера их «этажей в квадратиках» — 3, 3 и 4, так что во второй день мы должны установить блок 5 и один из блоков 1 и 2, все равно какой: 1 установи (1); установи (5) День 3-й. На землю и уже установленные блоки опираются 2 и 6. Их мы и устанавливаем: установи (2); установи (6) День 4-й. То же для блоков 7 и 8: установи (7); установи (8) День 5-й. Остался один блок 9: установи (9) А вот как выглядит вся программа целиком: установи (3); установи (4) установи (1); установи (5) установи (2); установи (6) установи (7); установи (8) установи (9); 17.8. Составьте алгоритм самой быстрой постройки здания с рисунка задачи, рассмотренной в начале этого раздела, тремя бригадами. 17.9. Докажите, что при заданном числе бригад никакое здание нельзя построить быстрее, чем посредством описанного алгоритма. 17.10. Напишите программы строительства зданий из задач 9.1 и 9.4 за самый короткий срок при помощи: а) двух бригад; б) трех бригад; в) четырех бригад. Структура задачника (послесловие для учителя) Часть А содержит задачи, не использующие условий. Анализ встречающихся здесь алгоритмов относительно прост: эти алгоритмы работают всегда одинаково. Часть А разбита на разделы, посвященные отдельным Исполнителям. Первые задачи в каждом разделе носят ознакомительный характер и позволяют школьникам освоить данный Исполнитель. Большое внимание в этой части уделено математическому содержанию изучаемых алгоритмов. Так, Водолей и Кузнечик тесно связаны с делимостью чисел. Удвоитель и Раздвоитель — с двоичной системой счисления. Черепаха и Чертежник — с различными геометрическими объектами и геометрическими преобразованиями. Во многих задачах на построение алгоритмов в части А задание содержит фразу: постарайтесь, чтобы Исполнитель выполнял как можно меньше команд. При этом не требуется доказывать оптимальность составленной программы. Этот вопрос можно выяснять, например, путем сравнения программ, написанных одноклассниками. Задачи на доказательное построение оптимальных алгоритмов представлены в части В. В части Б собраны задачи, требующие использования условий. Эта часть содержит два раздела, посвященные Исполнителям Удвоитель/Раз-двоитель и Робот. Согласно концепции курса простые условия — это лампочки на панели Исполнителя. Лампочка горит, если условие выполняется, и не горит, если оно ложно. Такой подход позволил авторам ввести в рассмотрение новый круг задач: определить поведение Исполнителя при выполнении программы, зная только значение его условий. Авторы надеются, что этот подход будет способствовать лучшему усвоению школьниками важных понятий истинности и ложности условий. Помимо стандартных упрг1жнений на освоение этих понятий, здесь содержатся и упражнения с обратной постановкой задачи: расставить на поле Робота стены так, чтобы условия имели заданные значения истинности и т. д. Сложные задачи сконцентрированы в части В. Сложность этих задач определяется, как правило, тем, что в них нужно доказывать некоторые строгие математические утверждения. Так, раздел 12 посвящен доказательному построению оптимального алгоритма для Удвоителя/Раздвоите-ля, раздел 14 — рекурсии, раздел 17 — доказательному построению оптимального алгоритма для Директора строительства и т. д. Мы старались разбить эти сложные задачи на более простые, выстроив их в логическую цепочку, доступную для восприятия и самостоятельного решения. Ряд задач в части В можно рассматривать как материалы для проекта. В качестве материалов для проекта могут служить разделы 12, 13, 15, 16, 17. Решения задач приведены в книге для учителя. Отсутствие решения, как правило, указывает на технический характер задачи или на наличие достаточного количества близких по характеру задач, решение которых приведено. Учебное издание Звонкин Александр Калманович Ландо Сергей Константинович Семенов Алексей Львович ИНФОРМАТИКА Учебник для 6 класса общеобразовательных учреждений Зав. редакцией Т. А. Бурмистрова Редактор А. В. Желонкин Младший редактор Н. В. Ноговицына Художник О. В. Попович Художественный редактор О. П. Богомолова Компьютерная графика: В. В. Брагин Техническое редактирование и компьютерная верстка Н. О. Рычковой Корректоры О. В. Крупенко, И. Н. Панкова, Г. Н. Смирнова Налоговая льгота — Общероссийский классификатор продукции ОК 005-93—953000. Изд. лиц. Серия ИД №05824 от 12.09.01. Подписано в печать 21.12.2005. Формат 70x90 */jg. Бумага офсетная. Гарнитура Школьная. Печать офсетная. Уч.-изд. л. 17 >ч<;хп о« форз. Тираж 10 000 экз. Заказ № 581. ■ i'l У lecTBO «Издательство «Просвещение». 127521, Москва, й проезд Марьиной рощи, 41. /дового Красного Знамени полиграфкомбинат детской :ССР*. 170040, г. Тверь, проспект 50 лет Октября, 46. Цена: ШЖ ПРОСВЕЩЕНИЕ ИЗДАТЕЛЬСТВО .ViivApii и IIII4U.I1I IU 11 XX S' —» 0СТГ>ОИОМИИ 'Х***-* Издательство «11рг)еве1цение« 127521, Москва, З'й проезд Марьиной рощи, 41 Тел.:(495)789-3040 Факс:(495)789-3041 E-mail: prosvC^^prosv.ru https://www.prosv.ru Выпускаем • Учебники • Методическую литературу • Научно-популярную литературу • Справочную литературу • Наглядные пособия и карты • Учебные мультимедийные курсы Обучаем Интернет-школа * Просвещение, ги * www.internet-school.ru Институт повышения квалификации работников образования www.prosv-ipk.ru Представляем На сайте издательства для наших покупателей • Каталог выпускаемой продукции • Ежемесячные новинки издательства • Планы печати учебной литературы • Адреса магазинов *Просвещение* в регионах Предлагаем Оптовикам и книготорговым структурам • Гибкую систему скидок • Крупный и мелкий опт со склада издательства • Контейнерную отгрузку во все регионы России и страны СНГ • Внимательное отношение к каждому! Служба «Книга—почтой» Заказ и отправка книг по почте 102001, Москва, а/я «Почтовый Торговый Дом» Тел.: (495) 540-6061 E-mail: prosvCu post.ru, zakazC^ptdom.ru https:// www.ptdom.ru Фирменные магазины «[1роске1цение» 119311, Москва, пр-т Вернадского, 11/19 Тел.:(495)930-5050 Тел./факс: (495) 930-5040 E-mail: mag-info(f^prosv.ru 115304, Москва, ул. Луганская, 7 Тел.: (495) 322-2822 E-mail: [email protected] Словарь понятий алгоритмики Параллельное программирование - программирование одновременной работы нескольких Исполнителей для решения общей задачи. Программа - последовательность действий Исполнителя,записанная на алгоритмическом языке с помощью процедур и конструкций. Простая команда - команда из набора команд Исполнителя. Процедура - программа с именем, оформленная специальным образом. Процедуры можно вызывать в программах наравне с простыми командами. Рекурсия - вызов процедурой самой себя непосредственно или через другие, промежуточные процедуры. Синтаксические правила - правила записи алгоритмов (программ) на алгоритмическом языке. Сложность программы - число строк в программе. Состояние Исполнителя - полный набор сведений об Исполнителе в некоторый момент выполнения программы. Стратегия игры - принципы поведения игрока в зависимости от действий противника. Таблица состояний - таблица, описывающая состояние Исполнителя после выполнения каждой команды некоторой программы. Условие - сведение о состоянии Исполнителя, которое может быть автоматически проверено. Эффективность программы - число шагов работы Исполнителя при выполнении данной программы. Эффективность программы зависит от начального состояния. ISBN 5-09-014569-5 9785090 145695 Курс «Информатика» позволяет: • освоить важные фрагменты математических основ информатики; • познакомиться с различными Исполнителями; • научиться предусматривать и анализировать обстоятельства и планировать свои действия; • разрабатывать и реализовывать простейшие алгоритмы; • анализировать эффективность выполнения алгоритмов; • развить общие мыслительно-коммуникативные способности; • сформировать общеучебные навыки.