Генератор Python: управление направлением движения и зоной разворота

Напишите решение на Python и проверьте его на странице.

Другие упражнения по этой теме: Генератор send в Python: задачи на состояние и управление потоком.

Зона разворота подъёмника

Автоматический подъёмник перемещается между этажами по целочисленной вертикальной шкале, принимая команды на перемещение или изменение параметров. Сопрограмма управления лифтом начинает работу на нулевом этаже с направлением движения вверх (+1) и заданной шириной зоны разворота. При вызове на целевой этаж контроллер соглашается на поездку, только если цель лежит по ходу текущего движения либо находится позади не дальше установленной зоны разворота.

Если вызов принят, кабина перемещается на указанный этаж, направление движения обновляется в сторону этого перемещения или сохраняется, если этаж совпал, а генератор возвращает фактическое пройденное расстояние. Отклонённый вызов оставляет подъёмник на месте, и сопрограмма отвечает значением -1.

Отдельная настроечная команда передаёт новую неотрицательную ширину зоны разворота. Лифт обновляет этот параметр без перемещения кабины и возвращает в ответ номер текущего этажа стоянки.

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

Что уже дано

В редакторе представлена заготовка функции reversal_lift(zone). Вспомогательные функции для тестирования уже доступны в окружении при выполнении, реализовывать их заново не требуется.

Что нужно сделать

Реализуйте функцию-генератор reversal_lift(zone).

Функция принимает неотрицательное целое число zone (от 0 до 1 000 000, включая подклассы int) — начальную ширину зоны разворота. Функция должна возвращать обычный неинициализированный генератор (сопрограмму).

Правила работы сопрограммы:

  • Инициализация: первый вызов next() или send(None) выполняет запуск сопрограммы и возвращает None. Автоматического прайминга внутри фабрики быть не должно.
  • Начальное состояние: кабина начинает работу на этаже 0, текущее направление движения — вверх (+1).
  • Команды перемещения: через .send(target_floor) передаётся целочисленный целевой этаж (от -1 000 000 до 1 000 000, включая подклассы int).
  • Запрос принимается, если целевой этаж лежит по направлению текущего движения либо позади текущего положения на расстоянии, не превышающем zone (включая точную границу зоны разворота).
  • При принятии вызова кабина перемещается на целевой этаж. Сопрограмма возвращает пройденное абсолютное расстояние abs(target_floor - current_floor) в виде целого числа. Направление движения обновляется в сторону перемещения (+1 при движении вверх, -1 при движении вниз). Если целевой этаж совпадает с текущим, направление движения не меняется.
  • При отклонении вызова кабина остаётся на прежнем этаже, её направление не изменяется, а сопрограмма возвращает -1.
  • Калибровка зоны разворота: через .send(("zone", new_zone)) передаётся кортеж с новой неотрицательной шириной зоны (от 0 до 1 000 000, включая подклассы int). Сопрограмма обновляет значение zone, не меняет положение и направление кабины, и возвращает текущий этаж стоянки в виде целого числа.
  • Сопрограмма поддерживает штатные методы завершения генератора close() и проброса исключений throw().
  • За время жизни одного генератора поступает от 0 до 1000 сообщений. В тестах может параллельно использоваться от 1 до 3 независимых экземпляров генератора.

Ввод и вывод

Стандартные потоки ввода stdin и вывода stdout в решении не используются: считывать ввод и вызывать print() не нужно. После выполнения кода учащегося проверяющая система считывает из пространства имён модуля функцию верхнего уровня reversal_lift и вызывает её с проверочными аргументами.

Пример использования

lift = reversal_lift(2)
print(next(lift))
print(lift.send(5))
print(lift.send(3))
print(lift.send(7))
print(lift.send(('zone', 4)))
print(lift.send(7))
lift.close()

Вывод:

None
5
2
-1
3
4
РешениеPython

Без регистрации. Гостевая проверка не сохраняет прогресс. Для сохранения перейдите к уроку.

Отправьте решение, чтобы увидеть результаты тестов.

Связанные задачи