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

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

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

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

                       К О Р Р Е К Т О Р


Глава 6. Преобразования, подсчеты, редактирование

6.1. Длина текста (<<dlina1.kor, dlina2.kor, dlina1.kor>>)

   Петя. Когда я пишу свои программы в университете на языке Си,
то  очень  часто использую процедуру подсчета длины текста.  Вот
интересно, можно ли этому научить Корректора?
   Вася. После  того, как мы  научили его азам арифметики, я ду-
маю, нет предела его возможностям!
   Папа. Интересная задача. Давайте я сначала сформулирую ее для
случая, когда длина текста не превышает девяти символов.

   Задача. <<dlina1.kor>> На  ленте  записан текст не длиннее 9
символов. Записать на  ленту его длину. В начальный момент окно
установлено на первый пустой символ перед текстом.

   Петя. Я  кажется  догадываюсь, почему  ограничена длина: если
текст небольшой, то для увеличения счетчика  символов  на  один,
можно использовать команду ПЛЮС из СКИ Корректора.
   Папа. Ты прав. Именно это я имел ввиду.
   Вася. Что вы называете счетчиком?
   Петя. Ну, обычно программисты выполняют подсчеты так. Заводят
специальную ячейку памяти - ее-то и называют счетчиком - и запи-
сывают в нее ноль. Затем устраивают цикл по  просмотру всех сим-
волов текста, в котором к счетчику каждый раз добавляется едини-
ца. Понятно, что когда цикл заканчивается, в счетчике оказывает-
ся нужное нам число.
   Вася. Понятно.  Я  предлагаю в качестве счетчика использовать
ящик.
   Петя. Почему бы и нет!
   Вася. Тогда основная процедура запишется так:

ЭТО Длина
 Обнуление_счетчика
 Работа
 Запись_ответа
КОНЕЦ

   Папа. Как вы запишите в ящик нуль?
   Вася. Ну, это  очень просто. В начальный момент окно установ-
лено на пустой  символ перед текстом.  Запишем на ленту  ноль  и
скопируем его в ящик. Последней  командой  я  восстанавливаю  на
ленте пустое место:

ЭТО Обнуление_счетчика
 ПИШИ 0
 ЯЩИК+
 ПИШИ ПУСТО
КОНЕЦ

   Папа. Хорошо. Теперь надо описать цикл  просмотра всех симво-
лов текста.
   Вася. Сначала я командой ВПРАВО перемещаю окно на первый сим-
вол, а затем записываю цикл ПОКА:

ЭТО Работа
 ВПРАВО
 ПОКА НЕ ПУСТО
 {
    Добавить_к_счетчику_1
    ВПРАВО
 }
КОНЕЦ

   Петя. Теперь мы подошли к самой сложной процедуре, увеличива-
ющей счетчик на один. Так  как  текст не длиннее 9 символов,  то
можно было бы использовать команду ПЛЮС,  но,  к  сожалению,  ее
нельзя применить к ящику.

   Вася. Да, ты прав. Придется:
   - идти в конец текста;
   - копировать ящик на ленту;
   - увеличивать цифру на ленте на один;
   - копировать полученное число в ящик;
   - стирать число на ленте;
   - возвращать окно на прежнее место в тексте.
   Петя. Для возврата окна  на  исходное место в текста придется
использовать рекурсивную процедуру с отложенной командой ВПРАВО,
если мы собираемся перемещать  окно влево. Позволь, я напишу эту
процедуру.
   Вася. Ну, вот самое интересное всегда отбирают у маленьких!
   Петя. Старик, не плачь, у тебя все еще впереди!

ЭТО Добавить_к_счетчику_1
  ВЛЕВО
  ЕСЛИ НЕ ПУСТО
   ТО Добавить_к_счетчику_1
   ИНАЧЕ
   {
     // Увеличение числа в ящике на 1
     ЯЩИК-
     ПЛЮС
     ЯЩИК+
     ПИШИ ПУСТО
   }
  ВПРАВО // Отложенная команда. Она
         // возвращает окно на текущее
         // место в тексте.
КОНЕЦ

   Вася. Да, получилось  красиво!  Ну, мне остается только напи-
сать процедуру для оформления ответа. Когда  цикл закончен, окно
смотрит на  первый пустой символ справа  от текста. Я  запишу на
его место пробел, затем знак "=" и число из ящика:

ЭТО Запись_ответа
 ПИШИ ПРОБЕЛ
 ВПРАВО
 ПИШИ =
 ВПРАВО
 ЯЩИК-
КОНЕЦ

   Папа. Молодцы! Только Корректору приходится постоянно переме-
щать окно в  конец  текста для  увеличения  счетчика на один.  Я
предлагаю этого не делать, а изменять счетчик прямо на месте.
   Вася. Это нельзя сделать, ведь команда  ПЛЮС действует только
на ячейку ленты.
   Папа. В СКИ  исполнителя есть еще одна команда, которая может
нам помочь.
   Петя. Ну, конечно, как я сразу не догадался - это команда ОБ-
МЕН!
   Вася. Да, в самом деле,  можно  обменять  местами  содержимое
ящика и ленты, добавить  один,  а затем восстановить ленту новым
обменом. Здорово! Вот новая процедура Добавить_к_счетчику_1:

ЭТО Добавить_к_счетчику_1
 ОБМЕН
 ПЛЮС
 ОБМЕН
КОНЕЦ

   Петя. Эта процедура  не такая хитрая, как прежняя, но гораздо
более эффективная - мы экономим Корректору просто уйму времени!

   Папа. Предлагаю  теперь  изменить  немного формулировку нашей
задачи.
   Задача. <<<<dlina2.kor>>  На ленте записан текст, число сим-
волов в котором не больше числа символов в алфавите Корректора.
Записать на ленту его длину. В начальный момент окно установле-
но на первый пустой символ перед текстом.
   Вася. Теперь на ленте  могут  быть гораздо более длинные тек-
сты.
   Петя. Новое ограничение на длину, я думаю, по-прежнему связа-
но с возможностями команды ПЛЮС.
   Папа. Ты прав!
   Вася. Если действовать прежним образом, то на десятом символе
в ящике получится буква "а", потом буква "б" и так далее.
   Петя. Понятно! После просмотра всего текста, надо записать на
ленту число  0 и добавить к нему единицу  столько раз, каков по-
рядковый номер символа  в ящике. Это  еще один цикл,  в  котором
можно использовать программу Плюс1, ее мы писали прошлый раз.
   Братья после  небольших  споров и раздумий записали следующую
программу:

ЭТО Большая_длина
 Обнуление_счетчика
 Работа
 Запись_ответа
КОНЕЦ
//-------------------------------------
ЭТО Обнуление_счетчика
 ПИШИ 0
 ЯЩИК+
 ПИШИ ПУСТО
КОНЕЦ
//-------------------------------------
ЭТО Работа
 ВПРАВО
 ПОКА НЕ ПУСТО
 {
    Добавить_к_счетчику_1
    ВПРАВО
 }
КОНЕЦ
//-------------------------------------
ЭТО Добавить_к_счетчику_1
 ОБМЕН
 ПЛЮС
 ОБМЕН
КОНЕЦ
//-------------------------------------
ЭТО Запись_ответа
 Подготовка
 Вычисления
КОНЕЦ
//-------------------------------------
ЭТО Подготовка
 ВЛЕВО
 ПОКА НЕ ПУСТО ВЛЕВО
 ВЛЕВО
 ПИШИ =
 ВЛЕВО
 ПИШИ 0
КОНЕЦ
//-------------------------------------
ЭТО Вычисления
 ОБМЕН
 ПОКА НЕ 0
 {
   МИНУС
   ОБМЕН
   Плюс_1
   ПОКА НЕ = ВПРАВО
   ВЛЕВО
   ОБМЕН
 }
 ОБМЕН
КОНЕЦ
//-------------------------------------
// К числу на ленте прибавить 1. В
// начальный момент в окошко видна
// младшая цифра числа.
//-------------------------------------
ЭТО Плюс_1
 ЕСЛИ 9
   ТО    Девять
   ИНАЧЕ Цифра_не_девять
КОНЕЦ
//-------------------------------------
ЭТО Цифра_не_девять
  ЕСЛИ ПУСТО
    ТО ПИШИ 1
    ИНАЧЕ ПЛЮС
КОНЕЦ
//-------------------------------------
ЭТО Девять
 ПИШИ 0
 ВЛЕВО
 Плюс_1
КОНЕЦ

   Папа. Хорошая программа!  Теперь  можно решить эту задачу для
любой длины текста.

   Задача.  <<<<dlina3.kor>>  На   ленте  записан  произвольный
текст. Вычислить его длину. В начальный момент окно установлено
на первый пустой символ перед текстом.

   Петя. Длина текста не может  быть  совсем  произвольной.  Ведь
лента не  бесконечная и на  ней, кроме самого текста, должен по-
меститься еще и ответ.
   Папа. Да, ты прав! Будем считать, что это условие выполнено.
   Вася. Я, кажется, знаю, как  решить  эту  задачу! Можно отка-
заться от ящика и устроить счетчик на ленте прямо перед текстом.
Тогда, правда, придется, как и  в  первом  решении, для подсчета
каждого символа текста  перемещать  окно к счетчику, добавлять к
нему один, а затем возвращаться на прежнее место.
   Папа. Зато программа получится более универсальной. Так всег-
да бывает: если в чем-то выигрываем, то в чем-то проигрываем.
   Петя. Закон сохранения качества программы!

   Пока Папа  и  Петя  упражнялись  в программистской философии,
трудолюбивый Вася  написал  и  запустил  на выполнение следующую
программу:

//-------------------------------------
ЭТО Любая_длина
 Обнуление_счетчика
 Работа
 Оформление_ответа
КОНЕЦ
//-------------------------------------
ЭТО Обнуление_счетчика
 ВЛЕВО
 ПИШИ 0
 ПОВТОРИ 2 ВПРАВО
КОНЕЦ
//-------------------------------------
ЭТО Работа
 ПОКА НЕ ПУСТО
 {
    Добавить_к_счетчику_1
    ВПРАВО
 }
КОНЕЦ
//-------------------------------------
ЭТО Добавить_к_счетчику_1
  ВЛЕВО
  ЕСЛИ НЕ ПУСТО
   ТО Добавить_к_счетчику_1
   ИНАЧЕ
   {
     // Увеличение числа
     // в счетчике на 1
     ВЛЕВО
     Плюс_1
     ПОКА НЕ ПУСТО ВПРАВО
   }
  ВПРАВО // Отложенная команда. Она
         // возвращает окно на текущее
         // место в тексте.
КОНЕЦ
//-------------------------------------
ЭТО Оформление_ответа
 ВЛЕВО
 ПОКА НЕ ПУСТО ВЛЕВО
 ПИШИ |
КОНЕЦ
//-------------------------------------
// К числу на ленте прибавить 1. В
// начальный момент в окошко видна
// младшая цифра числа.
//-------------------------------------
ЭТО Плюс_1
 ЕСЛИ 9
   ТО    Девять
   ИНАЧЕ Цифра_не_девять
КОНЕЦ
//-------------------------------------
ЭТО Цифра_не_девять
  ЕСЛИ ПУСТО
    ТО ПИШИ 1
    ИНАЧЕ ПЛЮС
КОНЕЦ
//-------------------------------------
ЭТО Девять
 ПИШИ 0
 ВЛЕВО
 Плюс_1
КОНЕЦ
//-------------------------------------

   Задача 1. На ленте записан  текст  не  длиннее длины алфавита
Корректора. Подсчитать число  букв "о" в нем. В начальный момент
окно установлено на первый пустой символ перед текстом.

   Задача 2. На ленте записано число.  Подсчитать сумму наимень-
шей и наибольшей  его цифры. В начальный момент окно установлено
на первый пустой символ перед текстом.

   Задача 3. На ленте записан  текст  не  длиннее длины алфавита
Корректора. Подсчитать число двойных символов в нем. В начальный
момент окно установлено на первый пустой символ перед текстом.

   Задача 4. На ленте записан  текст  не  длиннее длины алфавита
Корректора. Записать на ленту число слов в нем.  В начальный мо-
мент окно установлено на первый пустой символ перед текстом.

   Задача 5. Окно  установлено  на единственный символ на ленте.
Записать рядом с ним его порядковый номер в алфавите Корректора.

6.2. Корректор оправдывает свое имя.

   Петя. У  меня  есть предложение заняться редактированием тек-
ста, не зря же Корректор получил свое имя!
   Папа. Хорошая  идея. Сначала давайте вспомним разделение оши-
бок набора текста на три класса.
   Вася. Я помню! При вводе текста с клавиатуры компьютера можно
сделать кучу ошибок, но  большинство  из них укладываются на три
полочки:
        1) неверный символ - исправляется заменой;
        2) лишний символ - исправляется удалением;
        3) пропущенный символ - исправляется вставкой.

   Папа. Начнем  работать  по-порядку. Вот первая задача.

   Задача. На ленте записан текст, в котором все вхождения неко-
торого символа нужно  заменить на другой символ. В начальный мо-
мент среда имеет следующий вид:

         ┬─┬─┬─┬─┬─╦═╦─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬
         │░│░│░│░│░║t║z│ │т│е│к│с│т│░│░│░│░│░│░│░│░│░│
         ┴─┴─┴─┴─┴─╩═╩─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴

   Здесь через t  обозначен символ, подлежащий замене, через z -
символ, на который надо менять символ t.
   Например, конкретная начальная установка  может  иметь следу-
ющий вид:

         ┬─┬─┬─┬─┬─╦═╦─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬
         │░│░│░│░│░║а║о│ │к│а│л│е│с│а│░│░│░│░│░│░│░│░│
         ┴─┴─┴─┴─┴─╩═╩─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴

   Это означает, что в тексте "калеса" нужно все буквы "а" заме-
нить на букву "о".

   Вася. Предлагаю следующий алгоритм. Сначала в ящик копируется
символ t, подлежащий замене, а потом в цикле  каждый символ тек-
ста  сравнивается  с содержимым ящика. Если есть совпадение,  то
производится замена  символа  на ленте символом z, расположенным
перед текстом:

ЭТО Замена
 Подготовка
 ПОКА НЕ ПУСТО
 {
   ЕСЛИ Я=Л ТО Замена_символа
   ВПРАВО
 }
КОНЕЦ

ЭТО Подготовка
 ЯЩИК+
 ПОВТОРИ 3 ВПРАВО
КОНЕЦ

   Папа. Пока нет никаких возражений.
   Петя. В процедуре замены символа есть  одно неприятное место.
Когда в тексте обнаружен символ, подлежащий замене, нужно
     1) сходить за образцом z и заменить им символ на ленте;
     2) сходить за образцом t, для того чтобы продолжить поиск.

   Вася. Я придумал, как обойтись только одним походом за симво-
лом z, а за символом t не ходить!
   Петя. Рассказывай!
   Вася. Нам поможет команда ОБМЕН. Перед тем, как  идти за сим-
волом z, мы используем ее для временного хранения символа t (ко-
торый расположен  в ящике) на  ленте. Потом, когда в ящике будет
символ z, мы выполним еще один  ОБМЕН, и на ленту запишется z, а
в ящике окажется t - можно продолжать цикл поиска дальше!
   Петя. Здорово!
   Папа. Молодец!
   Вася. Вот окончание моей программы:

ЭТО Замена_символа
 ОБМЕН
 Взять_образец
 ОБМЕН
КОНЕЦ

ЭТО Взять_образец
 ВЛЕВО
 ЕСЛИ НЕ ПУСТО
  ТО Взять_образец
  ИНАЧЕ
  {
    ВЛЕВО
    ЯЩИК+
    ВПРАВО
  }
  ВПРАВО // Отложенная команда. Она
         // возвращает окно на текущее
         // место в тексте.
КОНЕЦ

   Папа. Теперь давайте решим задачу на удаление.

   Задача. На ленте расположен текст.  Перед  ним  через  пустое
место  записан  образец символа, все вхождения в текст  которого
подлежат удалению. В  начальный  момент окно установлено на сим-
вол-образец:

         ┬─┬─┬─┬─┬─╦═╦─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬
         │░│░│░│░│░║t║ │т│е│к│с│т│░│░│░│░│░│░│░│░│░│
         ┴─┴─┴─┴─┴─╩═╩─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴

   Вася. Сначала копируем образец в ящик, а затем  в цикле прос-
матриваем все символы текста:

ЭТО Удаление
 Подготовка
 ПОКА НЕ ПУСТО
 {
   ЕСЛИ Я=Л ТО Удаление_символа
   ВПРАВО
 }
КОНЕЦ

ЭТО Подготовка
 ЯЩИК+
 ПОВТОРИ 2 ВПРАВО
КОНЕЦ

   Петя. Как ты собираешься удалять символ?
   Вася. Ну, я запишу на него пустое место.
   Петя. Не годится! При удалении остаток  теста надо сдвигать
влево.
   Вася. Да, верно! Это я поторопился.
   Петя. И еще, представь себе,  что  удаляемый  символ в тексте
идет подряд несколько  раз.  Тогда твоя программа будет работать
неправильно.
   Вася. Почему?
   Петя. Когда  условная  команда,  расзоложенная первой в цикле
ПОКА, обнаруживает  символ, который подлежит удалению, то про-
исходит сдвиг текста, после чего окошко сдвигается вправо. А ес-
ли символ повторяется?
   Вася. Тогда он  копируется на место удаленного и уже исключа-
ется из проверки. Я изобразил это на рисунке:

Начальная установка среды:
         ┬─┬─┬─┬─┬─╦═╦─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬
         │░│░│░│░│░║1║ │1│1│2│2│2│░│░│░│░│░│░│░│░│░│
         ┴─┴─┴─┴─┴─╩═╩─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴

Проверка в цикле первого символа:
         ┬─┬─┬─┬─┬─┬─┬─╦═╦─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬
         │░│░│░│░│░│1│ ║1║1│2│2│2│░│░│░│░│░│░│░│░│░│
         ┴─┴─┴─┴─┴─┴─┴─╩═╩─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴
После удаления:
         ┬─┬─┬─┬─┬─┬─┬─╦═╦─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬
         │░│░│░│░│░│1│ ║1║2│2│2│░│░│░│░│░│░│░│░│░│░│
         ┴─┴─┴─┴─┴─┴─┴─╩═╩─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴

После команды ВПРАВО:
         ┬─┬─┬─┬─┬─┬─┬─┬─╦═╦─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬
         │░│░│░│░│░│1│ │1║2║2│2│░│░│░│░│░│░│░│░│░│░│
         ┴─┴─┴─┴─┴─┴─┴─┴─╩═╩─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴
                        │
                        └─ этот символ исключен из проверки

   Вася. Да, но как же преодолеть эту трудность?
   Петя. Очень просто. Вправо надо смещаться только тогда, когда
не было удаления. А если удаление было, надо текущий символ про-
верять снова!
   Вася. Понятно. Тогда начало моей программы будет таким:

ЭТО Удаление
 Подготовка
 ПОКА НЕ ПУСТО
 {
   ЕСЛИ Я=Л
    ТО    Удаление_символа
    ИНАЧЕ ВПРАВО
 }
КОНЕЦ

ЭТО Подготовка
 ЯЩИК+
 ПОВТОРИ 2 ВПРАВО
КОНЕЦ

   Петя. Вот теперь другое дело!

   Вася.  Работа  по удалению символа разделяется на две  части.
Сначала должен быть сдвиг текста, но он использует ящик. Значит,
после сдвига, придется сходить в начало текста за образцом:

ЭТО Удаление_символа
  Сдвиг_текста
  Копирование_образца
КОНЕЦ

   Процедуры сдвига текста и копирования образца будут рекурсив-
ными с отложенными командами, которые возвратят  окно в исходное
положение внутри текста:

ЭТО Сдвиг_текста
 ВПРАВО
 ЕСЛИ НЕ ПУСТО
  ТО
  {
    ЯЩИК+
    ВЛЕВО
    ЯЩИК-
    ВПРАВО
    Сдвиг_текста
  }
  ИНАЧЕ
  {
    // Стирание последнего символа
    ВЛЕВО
    ПИШИ ПУСТО
    ВПРАВО
  }
  ВЛЕВО // Отложенная команда. Она
        // возвращает окно на текущее
        // место в тексте.
КОНЕЦ

ЭТО Копирование_образца
  ВЛЕВО
  ЕСЛИ НЕ ПУСТО
   ТО    Копирование_образца
   ИНАЧЕ
   {
     ВЛЕВО
     ЯЩИК+
     ВПРАВО
   }
  ВПРАВО // Отложенная команда. Она
         // возвращает окно на текущее
         // место в тексте.
КОНЕЦ

   Папа. Хотелось бы избавить Корректора от утомительных походов
за образцом.
   Вася. А это возможно?
   Папа. Попробуй, сегодня ты уже предлагал красивое решения по-
добной задачи.
   Вася. Да, конечно, сохранить образец нам опять поможет коман-
да ОБМЕН. Вот новое решение:

ЭТО Удаление
 Подготовка
 ПОКА НЕ ПУСТО
 {
   ЕСЛИ Я=Л
    ТО    Удаление_символа
    ИНАЧЕ ВПРАВО
 }
КОНЕЦ

ЭТО Подготовка
 ЯЩИК+
 ПОВТОРИ 2 ВПРАВО
КОНЕЦ

ЭТО Удаление_символа
 ВПРАВО
 ЕСЛИ НЕ ПУСТО
  ТО
  {
    ОБМЕН // Образец на ленту
    ВЛЕВО
    ЯЩИК-
    ВПРАВО
    ОБМЕН // Образец в ящик
    Удаление_символа
  }
  ИНАЧЕ
  {
    // Стирание последнего символа
    ВЛЕВО
    ПИШИ ПУСТО
    ВПРАВО
  }
  ВЛЕВО // Отложенная команда. Она
        // возвращает окно на текущее
        // место в тексте.
КОНЕЦ

   Папа. Очень хорошо!  Ты  существенно сократил не только текст
программы, но и время ее исполнения. Теперь давайте решим задачу
на вставку.

   Задача. В тексте на ленте пропущено  слово "кот". Вставить  в
текст это слово  (вместе с последующим пробелом), если в началь-
ный момент окно установлено на место  вставки. Пример возможного
состояния среды показан на рисунке:

         ┬─┬─┬─┬─┬─┬─┬─╦═╦─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬─┬
         │░│п│о│ш│е│л│ ║в║ │с│а│р│а│й│░│░│░│░│░│░│░│
         ┴─┴─┴─┴─┴─┴─┴─╩═╩─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴

   Вася. Придется сдвигать текст  от  места вставки, но не влево
как при удалении, а вправж.
   Папа. На сколько клеток предполагается сдвиг?
   Вася. На  длину  вставляемого  слова плюс последующий пробел,
значит, на четыре клетки. Вот начало моей программы:

ЭТО Вставка
 Сдвиг
 Вставка_слова
КОНЕЦ

ЭТО Вставка_слова
 ПИШИ к
 ВПРАВО
 ПИШИ о
 ВПРАВО
 ПИШИ т
 ВПРАВО
 ПИШИ ПРОБЕЛ
КОНЕЦ

   Вася. Да, процедура Сдвиг оказалась не так проста, как я ожи-
дал... Надо переместить окно в конец текста и  оттуда начать пе-
ремещение текста посимвольно на 4  клетки  вправо.  Но вся труд-
ность  в  том, что нужно вовремя остановиться. Остановка  должна
произойти тогда,  когда перемещение достигнет клетки, на которую
в начальный момент  было установлено окно.  Я не знаю,  как  это
сделать.
   Петя. Здесь опять поможет рекурсия с  отложенной командой, но
эта команда - не команда из СКИ, а вызов процедуры,  которая вы-
полняет сдвиг символа на четыре клетки вправо:

ЭТО Сдвиг
 ВПРАВО
 ЕСЛИ НЕ ПУСТО ТО Сдвиг
 Сдвиг_символа // Отложенная команда,
               // она выполнится столько
               // раз, сколько команда
               // ВПРАВО
КОНЕЦ

ЭТО Сдвиг_символа
 ВЛЕВО
 ЯЩИК+
 ПОВТОРИ 4 ВПРАВО
 ЯЩИК-
 ПОВТОРИ 4 ВЛЕВО
КОНЕЦ

   Вася. Удивительно красивое решение! Даже не  верится, что оно
будет работать.

   Братья запустили программу на компьютере  и,  к  удивлению  и
восхищению Васи, она заработала без каких либо замечаний.


   Задача 6. На ленте записан текст. Убрать из  него лишние про-
белы (каждую группу пробелов заменить на один пробел). В началь-
ный момент окно установлено  на  первый пустой символ перед тек-
стом.

   Задача 7. На ленте записан текст.  Добавить  в  него  пробелы
после  знаков  препинания (.,!?:;), если они отсутствуют. В  на-
чальный  момент  окно установлено на первый пустой символ  перед
текстом.

   Задача 8. На ленте  записан  текст. В нем встречаются символы
#. Перед текстом записано слово, отделенное  от основного текста
символом |. Заменить в тексте все  символы # на это слово. В на-
чальный момент окно установлено на символ |, расположенный между
словом и текстом.

Задача 9.
   На ленте записан текст, заключенный в символы |  с обоих сто-
рон. Перед  текстом  записано двухсимвольное слово (оно отделено
от основного текста символом |).  Проверить,  входит  ли слово в
текст как  составная  часть.  Если вхождение найдено, установить
окно на его конец, в противном случае установить окно на послед-
ний символ | за концом текста. В начальный  момент окно установ-
лено на символ |, расположенный между словом и текстом.

   Задача 10. На ленте записан текст. Упорядочить его символы по
возрастанию их порядковых  номеров  в алфавите Корректора. В на-
чальный момент окно установлено на первый символ текста.
