ДРоботландский Университет 
2000/2001 учебный год
Курс 31 "Азы программирования"
-------------------------------------------------
     Р О Б О Т Л А Н Д С К О Е  П Р О Г Р А М М И Р О В А Н И Е

                                   (C) А.А. Дуванов

                                      Под редакцией
                                      Ю.А. Первина

                                      Пособие   распространяется
                                      только в рамках  Роботлан-
                                      дских  Курсов  и  является
                                      объектом авторского права.

Глава 5. Другой тип повторения

5.1. Когда неизвестно число повторений
   Петя. Я хочу  предложить  тебе необычную задачу. Вот посмотри
на мой рисунок:
              1  2  3  4  5  6  7  8  9  10
             ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
           1 │  │  │  │  │  │  │  │  │  │А │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤

   Буква "А" стоит в углу,  в  клетке (1,10). Ее надо удалить  с
поля.
   Вася. А где же Кукарача?
   Петя. Где-то в первой строке.
   Вася. Как же я напишу программу, не зная положения исполните-
ля?
   Петя. В этом-то  и  состоит задача: программа должна работать
для ЛЮБОГО положения Кукарачи в первой строке.
   Вася. Если я напишу ПОВТОРИ 9  ВПРАВО, то где бы ни был Кука-
рача, он всегда выбросит букву с поля.
   Петя. Да, так  поступить можно. Но чаще всего выполнение этой
команды будет заканчиваться аварийным сообщением "Не могу".
   Вася. Понятно. Но как же поступить? Ведь Кукарача должен дви-
гаться вправо, пока не толкнет букву "А". Число повторений зара-
нее неизвестно, значит, команда ПОВТОРИ здесь не годится.
   Петя. Ты верно подметил: надо двигаться вправо, пока не обна-
ружится буква "А". Именно так, с ключевого слова ПОКА, и начина-
ется еще  одна команда повторения.  Вот как ее надо написать для
нашей задачи:
                        ПОКА НЕ А ВПРАВО
   Вася. Замечательно! Это то, что нужно.
   Петя. В общем случае эта команда имеет следующий вид:

                      ПОКА условие команда

   Условие записывается точно так же, как и в команде ветвления.
Работает команда так:
     - Сначала проверяется условие.
     - Если условие ложно, выполнение команды повторения закан-
чивается.
     - Если условие истинно,  выполняется "команда", записанная
после условия,  и  все начинается сначала: проверяется условие,
выполняется команда и так далее.
   Вася. Значит, если  условие ложно с самого начала, то "коман-
да", записанная после условия, не выполнится ни разу?
   Петя. Правильно. Давай решим еще несколько  задач, чтобы при-
выкнуть к использованию этой важной команды.
   Задача 1. Найти проход в стене  и дойти до края поля (в деся-
том столбце).
              1  2  3  4  5  6  7  8  9  10
             ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
           1 │# │Ж │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           2 │  │Ж │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           3 │  │Ж │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           4 │  │Ж │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           5 │  │Ж │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           6 │  │Ж │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           7 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           8 │  │Ж │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           9 │  │Ж │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
          10 │  │Ж │  │  │  │  │  │  │  │  │
             └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘
   Петя. Здесь  тоже нельзя использовать команду ПОВТОРИ, потому
что расположение  прохода  неизвестно  (на  рисунке он изображен
приблизительно). Мы не знаем, сколько надо сделать шагов до про-
хода, значит, неизвестно, какое число повторений  надо указать в
этой команде. Что  же делать? Надо  идти вдоль стены  (кубики  с
буквой "Ж"), пока она есть. Потом пройти в обнаруженный проход.
     Вася. Я попробую записать это так:
              ЭТО Выход
               Поиск_прохода
               На_край_доски
              КОНЕЦ
   Итак, первая процедура написана, а вот как же искать проход?
   Петя. Толкать кубики, пока не обнаружится пустое место.
   Вася. Попробую так:
             ЭТО Поиск_прохода
               ПОКА НЕ ПУСТО Шаг
             КОНЕЦ
   Петя. Команда Шаг не выполнится  ни  разу.  Ведь в начальный
момент Кукарача  не толкал кубики, и  поэтому условие в  ПОКА -
ложно.
   Вася. Хорошо, тогда я напишу так:
            ЭТО Поиск_прохода
             ВПРАВО
             ПОКА НЕ ПУСТО Шаг
            КОНЕЦ
   Петя. Это другое дело. Продолжай дальше.
   Вася. Теперь напишу процедуру Шаг:
            ЭТО Шаг
             // вернуться в первый столбец
             ВЛЕВО
             // шагнуть на следующую строку
             ВНИЗ
             // толкнуть кубик
             ВПРАВО
            КОНЕЦ
   Петя. Очень хорошо.
   Вася.  Теперь  осталось  написать  совсем  простую  процедуру
На_край_доски:
           ЭТО На_край_доски
             ПОВТОРИ 8 ВПРАВО
           КОНЕЦ
   Петя. Не  мог бы ты привести примеры на  цикл ПОКА из повсед-
невной жизни?
   После бурного  обсуждения петиного вопроса у братьев возникли
следующие примеры.
     1) Пока  гвоздь  не забит, ударяй по нему молотком.
     2) Переход улицы: пока идут машины, стой у перехода.
     3) Пока кастрюля грязная, три ее щеткой.
     4) Пока бочка не полна лей в нее воду из шланга.
     5) Куй железо, пока горячо.
     6) Иди на север, пока не выйдешь к реке.
   Во всех  этих примерах можно выделить повторяющиеся действия,
но число  повторений заранее неизвестно. Момент окончания повто-
рений  определяется  некоторым  условием, которое проверяется  в
процессе выполнения работы.

Вопросы и задания
     1. В каких случаях при программировании придется  восполь-
зоваться командой ПОКА, а в каких - командой ПОВТОРИ:
     а) Кукарача спускается  по  диагонали  из  клетки  (1,1) до
буквы "С", расположенной в клетке (8,8).
     б) Кукарача спускается  по  диагонали  из  клетки (1,1) до
буквы "С", расположенной где-то на этой диагонали.
     в) Робот-станок должен изготовить 100 одинаковых деталей.
     г) Робот-станок должен изготовлять одинаковые детали в те-
чении дневной рабочей смены.
     д) Робот-станок  должен  изготовлять одинаковые  детали до
тех пор, пока у него не кончатся заготовки.
     е) Компьютерная программа должна  обрабатывать  длительное
нажатие клавиши на клавиатуре.
     ж) Автомат, отключающий двигатель  стиральной машины через
3 минуты после включения.
     з) Автомат, отключающий двигатель  стиральной машины через
3 000 оборотов двигателя.

5.2. Как обмануть интерпретатор
   Петя. Все правильно. Я покажу тебе еще одну команду языка Ку-
карачи. Это команда называется СОСТАВНОЙ. Ее единственное назна-
чение - объединять несколько команд в одну группу:
                  {
                    команды
                  }
   Вася. А зачем нужна эта команда?
   Петя. Ну, ты знаешь, что многие конструкции языка требуют на-
писания в своем составе только одной команды. Эти требование от-
носятся к условной команде:
                ЕСЛИ условие
                 ТО    команда1  <── только одна команда!
                 ИНАЧЕ команда2  <── только одна команда!
и к командам повторения:
               ПОВТОРИ число команда  <── только одна команда!
               ПОКА условие команда   <── только одна команда!
   Используя составную  команду, можно "обмануть"  интерпретатор
программ. Вот, например,  как  можно переписать твою программу с
использованием составной команды:
              ЭТО Выход
               // Поиск прохода
               ВПРАВО
               ПОКА НЕ ПУСТО
               {
                 // вернуться в первый столбец
                 ВЛЕВО
                 // шагнуть на следующую строку
                 ВНИЗ
                 // толкнуть кубик
                 ВПРАВО
               }
               // На край доски
               ПОВТОРИ 8 ВПРАВО
              КОНЕЦ
   Вася. Программа получилась более компактной.
   Петя. Да,  но  использовать составную команду надо осторожно.
Часто предпочтительней  написать  много  маленьких процедур, чем
всю работу  описывать в одной  длинной программе. Мы с тобой уже
говорили о преимуществе процедурного программирования.
   Вася. Так как же быть?  Использовать  составную  команду  или
нет?
   Петя. Истина как всегда лежит посредине. Использовать, но ра-
зумно: там, где  это не ухудшит наглядность текста программы, не
затруднит программирование и не увеличит ее длину.
   Вася. Как может составная команда увеличить длину программы?
   Петя. Если одни  и те же действия должны выполняться неоднок-
ратно в разных частях программы, то,  конечно, выгоднее оформить
их в отдельную процедуру, а не пользоваться составной командой.
   Вася. Понятно.
   Петя. Продолжим решения задач с использованием команды ПОКА.
   Задача  2. Найти  и  вытолкнуть с поля  кубик  с буквой  "А".
(<<task501.coc>>)

              1  2  3  4  5  6  7  8  9  10
             ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
           1 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           2 │? │? │? │? │? │? │? │? │? │? │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           3 │# │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           4 │  │  │  │  │  │  │  │  │  │  │

   Вася. Вот мое решение:

              ЭТО Поиск_А
               // Испытание первого кубика
               ВВЕРХ
               ПОКА НЕ А
               {
                 // Возврат в третью строку
                 ВНИЗ
                 // Смещение к следующему кубику
                 ВПРАВО
                 // Проверка кубика
                 ВВЕРХ
               }
               // Выбрасывание букву А с поля
               ВВЕРХ
              КОНЕЦ

|* единство стиля в комментариях: все в инфинитиве


Вопросы и задания
     1. Когда лучше  воспользоваться дополнительной процедурой,
а когда составной командой?

Практикум
   1. Загнать мяч  (символ  "*")  в корзину, образованную буквами
"К". Заодно "починить" корзину  -  придвинуть первую букву "К" к
остальным. Положение корзины заранее неизвестно, известно  толь-
ко,  что   ее   верхний   край   расположен   на  пятой  строке.
(<<task503.coc>>)

3 │  │  │  │  │  │  │  │  │  │  │   3 │  │  │  │  │  │  │  │  │  │  │
  ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤     ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
4 │  │* │  │  │  │  │  │  │  │  │   4 │  │  │  │  │  │  │  │# │  │  │
  ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤     ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
5 │# │  │  │  │  │К │  │  │К │  │─> 5 │  │  │  │  │  │  │К │* │К │  │
  ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤     ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
6 │  │  │  │  │  │  │  │К │  │  │   6 │  │  │  │  │  │  │  │К │  │  │
  ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤     ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
7 │  │  │  │  │  │  │  │  │  │  │   7 │  │  │  │  │  │  │  │  │  │  │

   2. Нарастить стену на один кирпич (кирпич изображается буквой
"Ж"). После работы стена должна сместиться в шестой столбец. На
рисунке показана наибольшая возможная длина ненаращенной стены.
(<<task504.coc>>)
              1  2  3  4  5  6  7  8  9  10
             ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
           1 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           2 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           3 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           4 │  │  │  │  │Ж │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           5 │  │  │  │  │Ж │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           6 │  │  │  │  │Ж │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           7 │  │  │  │  │Ж │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           8 │  │  │  │  │Ж │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           9 │  │  │  │Ж │Ж │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
          10 │  │  │  │# │Ж │  │  │  │  │  │
             └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘

     3. Провести исполнителя по прямоугольнику А-Б-В-Г. Размеры
прямоугольника заранее неизвестны. (<<task502.coc>>)
              1  2  3  4  5  6  7  8  9  10
             ┌──┬──┬──┬──┬──┬──┬──┬──┬──┬──┐
           1 │Г │# │  │  │  │  │  │А │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           2 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           3 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           4 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           5 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           6 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           7 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           8 │  │  │  │  │  │  │  │  │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
           9 │В │  │  │  │  │  │  │Б │  │  │
             ├──┼──┼──┼──┼──┼──┼──┼──┼──┼──┤
          10 │  │  │  │  │  │  │  │  │  │  │
             └──┴──┴──┴──┴──┴──┴──┴──┴──┴──┘

     4. На одном из перевернутых кубиков  в  первом  столбце  -
буква "Ш". Найдите ее и составьте слово ИШАК. Букву "Ф"  с поля
надо убрать. (<<task505.coc>>)
                1 2 3 4 5 6 7 8 9 10
               ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
             1 │ │ │ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             2 │#│?│ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             3 │ │?│ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             4 │ │?│ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             5 │ │?│ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             6 │ │?│ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             7 │ │?│ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             8 │ │?│ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             9 │ │ │ │Ф│ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             10│ │ │ │ │И│ │А│К│ │ │
               └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘

     5. На  одном  из перевернутых кубиков в пятой строке  поля
Кукарачи - буква "Ь". Найдите ее и составьте слово МЫШЬ. В пер-
вом  столбце  третьей строки расположена буква "Ф"  -  ее  надо
спихнуть в ров. (<<task506.coc>>)

                1 2 3 4 5 6 7 8 9 10
               ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
             1 │М│Ы│Ш│ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             2 │ │ │ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             3 │Ф│ │ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             4 │ │ │ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             5 │ │?│?│?│?│?│?│?│?│ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             6 │ │ │ │ │ │ │ │ │#│ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             7 │ │ │ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             8 │ │ │ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             9 │ │ │ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             10│ │ │ │ │ │ │ │ │ │ │
               └─┴─┴─┴─┴─┴─┴─┴─┴─┴─┘

   6. Во второй строке со второй  позиции  записано  число,  все
цифры которого разные. Упорядочить цифры числа в порядке возрас-
тания, если  известно, что среди  цифр числа нет нулей и единиц.
Букву Н, расположенную в клетке (1,1), удалить с поля. На рисун-
ке  показано   возможное  состояние  среды  в  начальный  момент
(<<task507.coc>>):

                1 2 3 4 5 6 7 8 9 10
               ┌─┬─┬─┬─┬─┬─┬─┬─┬─┬─┐
             1 │Н│#│ │ │ │ │ │ │ │ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             2 │ │4│6│7│8│3│9│2│5│ │
               ├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
             3 │ │ │ │ │ │ │ │ │ │ │
