Задание №15 — Алгоритмы и программирование
Исполнитель Робот умеет перемещаться по лабиринту, начерченному на плоскости, разбитой на клетки. Между соседними (по сторонам) клетками может стоять стена, через которую Робот пройти не может.
У Робота есть девять команд. Четыре команды – это команды-приказы:
вверх вниз влево вправо
При выполнении любой из этих команд Робот перемещается на одну клетку соответственно: вверх ↑, вниз ↓, влево ←, вправо →. Если Робот получит команду передвижения сквозь стену, то он разрушится.
Также у Робота есть команда закрасить,при которойзакрашивается клетка, в которой Робот находится в настоящий момент.
Ещё четыре команды – это команды проверки условий. Эти команды проверяют, свободен ли путь для Робота в каждом из четырёх возможных направлений:
сверху свободно снизу свободно слева свободно справа свободно
Эти команды можно использовать вместе с условием «eсли», имеющим следующий вид:
если условие то
последовательность команд
все
Здесь условие – одна из команд проверки условия.
Последовательность команд – это одна или несколько любых команд-приказов.
Например, для передвижения на одну клетку вправо, если справа нет стенки, и закрашивания клетки, можно использовать такой алгоритм:
если справа свободно то
вправо
закрасить
все
В одном условии можно использовать несколько команд проверки условий, применяя логические связки и, или, не, например:
если (справа свободно) и (не снизу свободно) то
вправо
все
Для повторения последовательности команд можно использовать цикл «пока», имеющий следующий вид:
нц пока условие
последовательность команд
кц
Например, для движения вправо, пока это возможно, можно использовать следующий алгоритм:
нц пока справа свободно
вправо
кц
Выполните задание.
На бесконечном поле имеются две одинаковые горизонтальные стены и одна вертикальная, соединяющая левые концы стен. Длины стен неизвестны. Робот находится в одной из клеток, расположенных между правыми краями горизонтальных стен.
На рисункеуказан один из возможных способов расположения стен и Робота (Робот обозначен буквой «Р»).

Напишите для Робота алгоритм, закрашивающий все клетки, расположенные левее вертикальной стены непосредственно рядом с ней. Робот должен закрасить только клетки, удовлетворяющие данному условию. Например, для приведённого выше рисунка Робот должен закрасить следующие клетки (см. рисунок).

Конечное расположение Робота может быть произвольным. Алгоритм должен решать задачу для произвольного размера и любого допустимого расположения стен. При исполнении алгоритма Робот не должен разрушиться, выполнение алгоритма должно завершиться.
Алгоритм может быть выполнен в среде формального исполнителя или записан в текстовом редакторе.
Сохраните алгоритм в формате программы Кумир или в текстовом файле. Название файла и каталог для сохранения Вам сообщат организаторы экзамена.
Проверка решения с помощью ИИ доступна авторизованным пользователям
Решение.
Для решения задачи нам необходимо переместить Робота из начальной позиции (внутри П-образной конструкции) в позицию слева от вертикальной стены и закрасить клетки вдоль неё. Поскольку длины стен неизвестны, мы будем использовать циклы пока.
Шаг 1: Движение к вертикальной стене.
Робот находится между двумя горизонтальными стенами. Чтобы добраться до вертикальной стены, которая соединяет их слева, Роботу нужно двигаться влево до тех пор, пока путь свободен.
нц пока слева свободно
влево
кц
Шаг 2: Выход за пределы конструкции.
Теперь Робот упёрся в вертикальную стену. Чтобы закрасить клетки с её внешней (левой) стороны, нам нужно сначала выйти из "коридора". Для этого поднимемся вверх вдоль стены, пока не достигнем угла.
нц пока не сверху свободно
влево (этот шаг невозможен, так как слева стена, поэтому сначала нужно подняться)
Исправим логику: сначала поднимемся до верхней горизонтальной стены, затем обойдём её.
нц пока сверху свободно
вверх
кц
Теперь Робот в верхнем левом углу внутри конструкции. Чтобы выйти наружу, нужно пройти влево (там стена закончится, так как вертикальная стена соединяет левые концы). Но по условию вертикальная стена соединяет концы, значит, над Роботом — горизонтальная стена. Пройдём влево до конца горизонтальной стены? Нет, проще подняться выше стены.
Шаг 3: Правильный обход стены.
1. Двигаемся влево до упора в вертикальную стену:
нц пока слева свободно
влево
кц
2. Двигаемся вверх до упора в верхнюю горизонтальную стену:
нц пока сверху свободно
вверх
кц
3. Теперь Робот в углу. Чтобы попасть на левую сторону, нужно обойти стену. Сначала поднимемся выше горизонтальной стены (если бы над нами была стена, но мы уже упёрлись в неё). Нам нужно выйти за вертикальную стену. Для этого:
Поднимемся на одну клетку вверх (перепрыгнем горизонтальную стену нельзя, нужно пройти влево). Но стена мешает.
Уточнение: На рисунке видно, что вертикальная стена является левым краем. Пройдём вверх до конца, затем влево, затем вниз.
нц пока не сверху свободно (идем вдоль горизонтальной стены влево) - не подходит, так как мы внутри.
Оптимальный алгоритм:
1. Идем влево до упора: нц пока слева свободно влево кц
2. Идем вверх до упора: нц пока сверху свободно вверх кц
3. Теперь мы в верхнем левом внутреннем углу. Чтобы выйти:
Нужно пройти вдоль верхней стены вправо, пока она не кончится, выйти вверх, и вернуться влево. Но это сложно.
Проще: Вдоль вертикальной стены внутри всегда можно пройти вниз или вверх. Дойдем до нижнего конца:
нц пока снизу свободно вниз кц
Теперь мы в нижнем левом внутреннем углу. Ниже — горизонтальная стена. Слева — вертикальная.
Выйдем вправо до конца нижней стены:
нц пока не снизу свободно вправо кц
Теперь мы за краем нижней стены. Спустимся вниз: вниз.
Теперь идем влево, пока не окажемся левее вертикальной стены:
нц пока слева свободно влево кц
Теперь мы снизу-слева от конструкции. Поднимемся к началу вертикальной стены:
вверх
нц пока слева свободно вверх кц (проходим пустоту до уровня стены)
Теперь мы стоим слева от вертикальной стены.
Шаг 4: Закрашивание.
Пока справа стена, закрашиваем и движемся вверх:
нц пока не справа свободно
закрасить
вверх
кц
Итоговый код:
нц пока слева свободно
влево
кц
нц пока снизу свободно
вниз
кц
нц пока не снизу свободно
вправо
кц
вниз
нц пока слева свободно
влево
кц
вверх
нц пока справа свободно
вверх
кц
нц пока не справа свободно
закрасить
вверх
кц
Ответ:
алг
нач
нц пока слева свободно
влево
кц
нц пока снизу свободно
вниз
кц
нц пока не снизу свободно
вправо
кц
вниз
нц пока слева свободно
влево
кц
нц пока справа свободно
вверх
кц
нц пока не справа свободно
закрасить
вверх
кц
кон
Источник: ФИПИ