Однопроходный итератор Python: читайте по одной серии одинаковых элементов

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

Другие упражнения по этой теме: Itertools в Python: задачи на комбинации, groupby и ленивые потоки.

Сеансовый диспетчер серий

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

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

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

Что уже дано

В среде выполнения доступны класс SessionDispatcher и фабрика make_session_dispatcher(codes). Экземпляр диспетчера предоставляет изменяемое состояние:

  • source — однопроходный итератор категорийных кодов;
  • pending — сохранённый граничный код (изначально None);
  • has_pending — булев флаг наличия сохранённого кода (изначально False).

Также доступна функция observe_group_sessions для локальной проверки работы диспетчера с однопроходным источником. Вам предстоит реализовать только функцию next_session.

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

Реализуйте функцию next_session(dispatcher).

Она принимает объект dispatcher и возвращает список (list или его подкласс) кодов, составляющих очередную непрерывную серию подряд идущих одинаковых категорий в порядке их появления.

Требования к поведению:

  • Каждый вызов возвращает ровно одну полную серию подряд идущих одинаковых категорий. Одинаковые категории, разделённые контейнерами другого типа, образуют раздельные сессии.
  • Сравнение категорий выполняется по обычному строковому равенству.
  • Чтобы зафиксировать конец текущей серии, требуется прочитать первый контейнер со следующим кодом. Этот граничный элемент необходимо сохранить в dispatcher.pending, отметив его наличие через dispatcher.has_pending = True.
  • Очередной сеанс обязан учесть сохранённый ранее граничный элемент перед чтением оставшегося потока dispatcher.source. Когда сохранённый код взят в работу, признак has_pending снимается.
  • Запрещено вычитывать данные за пределами первого отличающегося элемента текущей серии или материализовать поток source целиком.
  • По достижении конца потока возвращается последняя собранная серия. Если доступных элементов больше нет, возвращается пустой список []. Все последующие вызовы для исчерпанного диспетчера также должны возвращать [].
  • Состояние принадлежит переданному экземпляру диспетчера: независимые диспетчеры не влияют на работу друг друга.

Ограничения:

  • Категорийные коды — непустые строки от 1 до 20 ASCII-букв.
  • Общее количество кодов в источнике — от 0 до 1000.
  • Число вызовов next_session к одному диспетчеру — от 0 до 1100.

Ввод и вывод

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

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

dispatcher = make_session_dispatcher(iter(['A', 'A', 'B', 'A']))
print(next_session(dispatcher))
print(next_session(dispatcher))
print(next_session(dispatcher))
print(next_session(dispatcher))

Вывод:

['A', 'A']
['B']
['A']
[]
РешениеPython

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

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

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