Send() в Python: накопление импульсов и квантование смещения

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

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

Квантование шагов привода

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

Когда порог достигнут, привод совершает максимально возможное число целых шагов в направлении знака регистра, оставляет в регистре остаток от деления с тем же знаком и возвращает число сделанных шагов со знаком. Если же накопленной величины недостаточно для шага, вал остаётся неподвижным, а результатом становится ноль. Отдельная команда калибровки позволяет задать новый положительный квант: шаг пересчитывается без движения вала, регистр сохраняет прежнее значение, а в ответ сообщается текущее накопленное смещение.

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

Что уже дано

В редакторе объявлена заготовка функции quantized_steps(quantum), которую необходимо реализовать. При выполнении кода в тестовом окружении также доступны вспомогательные функции наблюдения observe_quantized_steps и observe_quantized_subclass_inputs, реализовывать их не требуется.

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

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

Параметр quantum принимает положительное целое число от 1 до 1 000 000 (допускаются также подклассы int).

Функция должна возвращать стандартный неинициализированный генератор Python со следующим поведением:

  • Функция не должна выполнять прайминг автоматически: первый вызов next() или send(None) запускает генератор и возвращает None.
  • Все последующие сообщения, передаваемые через send(), представляют собой либо числовой импульс, либо команду калибровки.
  • Внутренний регистр накопленного смещения изначально равен 0.
  • Числовой импульс передаётся как целое число со знаком от -1 000 000 до 1 000 000 (включая 0 и подклассы int). При получении импульса его значение прибавляется к регистру:
  • если абсолютное значение регистра abs(register) >= quantum, генератор вычисляет максимальное число полных шагов того же знака, уменьшает абсолютную величину регистра на величину сделанных шагов (сохраняя знак остатка) и возвращает число сделанных шагов со знаком;
  • если abs(register) < quantum, генератор сохраняет накопленное значение в регистре и возвращает целое число 0.
  • Команда калибровки передаётся в виде кортежа ("quantum", new_quantum), где new_quantum — положительное целое число в диапазоне от 1 до 1 000 000. При её получении значение кванта заменяется на new_quantum без изменения регистра и без движения вала, а генератор возвращает текущее неизменённое значение регистра со знаком. Следующий числовой импульс (включая 0) использует уже новый квант.
  • Все числовые ответы должны быть целочисленными (int), а не вещественными числами float.
  • Независимо созданные генераторы (от 1 до 3 экземпляров, до 1000 сообщений на каждый) должны сохранять собственное изолированное состояние и корректно поддерживать закрытие через .close().

Ввод и вывод

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

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

q = quantized_steps(5)
print(next(q))
print(q.send(12))
print(q.send(('quantum', 3)))
print(q.send(-11))
q.close()

Вывод:

None
2
2
-3
РешениеPython

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

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

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