Задача понятна. Мы трактуем «ниши по периметру» как клетки (ниши) вдоль границы прямоугольника, обходящие по часовой стрелке. Роботу нужно последовательно перейти в следующую по часовой стрелке нишу и покрасить её.
Я дам подробное решение и рабочий пример кода на Python. Уточню допущения, чтобы было понятно, как адаптировать под задачу в учебной среде.
Что мы считаем за начало и как обходить
- Прямоугольник задан размерами w x h клеток по периметру (w — число клеток по горизонтали, h — по вертикали).
- Ниши — это клетки на краю прямоугольника. Периметр состоит из L = 2w + 2h - 4 клеток.
- Мы начинаем, например, в положении (0, 0) и смотрим вправо (на восток).
- Движение к следующей по часовой стрелке ниши всегда происходит по соседним клеткам по границе: после (x,0) идёт (x+1,0) и т.д., в конце верхней стороны поворачиваем направо и идём вниз и так далее. Это означает, что при переходе мы всегда делаем право-оборот на каждом углу.
Алгоритм
- Построить список координат всех ниш по периметру в порядке обхода по часовой стрелке, начиная с верхнего лева угла (0,0):
- верхняя сторона: (0,0) … (w-1,0)
- правая сторона: (w-1,1) … (w-1,h-1)
- нижняя сторона: (w-2,h-1) … (0,h-1) (если h > 1)
- левая сторона: (0,h-2) … (0,1) (если w > 1)
- Затем пройти по этому списку: для каждой следующей клетки — повернуть робота в нужное направление (правый поворот до нужной стороны) и двинуться в эту клетку, покрасить её.
- Повторить до конца списка.
Псевдокод понятен и легко адаптируется под любой язык.
Пример реализации на Python
- Программа генерирует путь по периметру и имитирует движение робота по этому пути, покрашивая каждую посещаемую нишу.
- В реальном роботе вместо принтов можно вызывать функции движка: повернуть, пройти на шаг вперёд, покрасить.
Код:
# Решение: обход периметра по часовой стрелке и покраска каждой ниши
def generate_perimeter_path(w, h):
"""
Возвращает список координат ниш по периметру в порядке обхода по часовой стрелке.
Координаты начинаются в верхнем левом углу (0,0).
"""
path = []
# верхняя сторона (левая->правая)
for x in range(0, w):
path.append((x, 0))
# правая сторона (верхняя -> нижняя), пропускаем уже учтенный угол (w-1,0)
for y in range(1, h):
path.append((w - 1, y))
# нижняя сторона (правая -> левая), если есть нижняя строка
if h > 1:
for x in range(w - 2, -1, -1):
path.append((x, h - 1))
# левая сторона (нижняя -> верхняя), пропуская углы
if w > 1:
for y in range(h - 2, 0, -1):
path.append((0, y))
return path
def rotate_clockwise(direction):
order = ['N', 'E', 'S', 'W'] # clockwise
idx = order.index(direction)
return order[(idx + 1) % 4]
def direction_from_delta(dx, dy):
if dx == 1 and dy == 0:
return 'E'
if dx == -1 and dy == 0:
return 'W'
if dx == 0 and dy == 1:
return 'S' # предполагаем, что y растет вниз
if dx == 0 and dy == -1:
return 'N'
return None
def traverse_perimeter_and_paint(w, h):
path = generate_perimeter_path(w, h) # список ниш по периметру
if not path:
return
pos = path[0] # начинаем в первой нише
painted = [pos] # дошли до первой ниши и покрасили её
current_dir = 'E' # ориентируемся по умолчанию на восток
# имитация покраски первой ниши
# print(f"Painted {pos}")
for next_pos in path[1:]:
dx = next_pos[0] - pos[0]
dy = next_pos[1] - pos[1]
target_dir = direction_from_delta(dx, dy)
# поворачиваемся вправо до нужного направления
while current_dir != target_dir:
current_dir = rotate_clockwise(current_dir)
# двигаемся в следующую нишу
pos = next_pos
painted.append(pos)
# покраска
# print(f"Moved to {pos}, painted.")
return path, painted
# Пример использования
if __name__ == "__main__":
w, h = 5, 3 # пример размера прямоугольника (кол-во ниш по ширине и высоте)
path, painted = traverse_perimeter_and_paint(w, h)
print("Путь обхода по периметру (координаты ниш):")
print(path)
print("Количество ниш, покрашено:", len(painted))
Как использовать этот код
- Задайте размеры прямоугольника: w — количество ниш вдоль верхней стороны, h — количество ниш вдоль левой стороны (то есть общее число ниш по периметру будет 2w + 2h - 4).
- Функция traverse_perimeter_and_paint вернёт путь и список посещённых ниш. В реальном роботе замените этапы поворота и движения на вызовы API вашего робота:
- повернуть(направление)
- двигаться_вперед(один_шаг)
- покрасить()
Пояснения по шагам
- Мы явно строим полный перечень ниш по периметру в clockwise-порядке. Это позволяет роботу «включаться» в следующую нишу без догадок, просто идём по следующей клетке.
- При переходе между соседними нишами робот всегда делает шаг на одну клетку вправо/вниз/влево/вверх, что соответствует переходу к соседнему элементу в пути.
- В примере начальная ориентация — восток; на каждом шаге робот поворачивает вправо до нужного направления, поскольку обход по периметру предполагает последовательные повороты на 90 градусов вправо.
Дополнительные заметки
- Если у вас другой метод задания начала обхода (например, старт в другой нише или старт с иной ориентацией), просто сгенерируйте путь периметра так, чтобы первая ниша соответствовала вашему старту.
- При особых случаях (например, w = 1 или h = 1) код всё равно корректно формирует путь вдоль единственной линии периметра; можно добавить явную обработку граничных условий, если требуется.
- Если нужен обход не по периметру, а по конкретной карте ниш внутри зала, дайте дополнительные параметры — тогда адаптирую решение под задачу.
Если хочешь, могу привести варианты на других языках (C++, Java) или показать версию, которая напрямую командует реального робота через ваш API движения и покраски.