"""Модуль, содержащий функции для чистки интервалов. Под 'чисткой' подразумевается: - удаление меньших интервалов, полностью входящих в большие (поглощение) - расширение пересекающихся интервалов (сумма интервалов) """ def absorb_small_included_intervals(intervals: list) -> list: """Возвращает список интервалов без вложенных интервалов. Вложенный интервал - интервал меньшего размера, полностью входящий в больший. Стоит учитывать, что функция работает только если интервалы совпадают по началу или концу, если интервалы входят друг в друга частично (пересекаются) -- здесь мы их не обрабатываем. """ # запоминаем самый перевый интервал, раньше него интервалов не # будет. Если текущий интервал входит в последний добавленный # нами, т.е. он заканчивается раньше, чем тот который мы добавили, # то мы его не добавляем в результат, так как он вложенный big_intervals = [intervals[0]] for i in range(1, len(intervals)): if big_intervals[-1][1] >= intervals[i][1]: continue else: big_intervals.append(intervals[i]) return big_intervals def merge_intersected_intervals(intervals) -> list: """Возвращает расширенные интервалы. Расширенные интервалы -- это интервалы, состоящие из суммы частично пересекающихся интервалов.""" # запоминаем самый первый интервал. Проходимся по списку, и если # начало текущего интервала меньше, чем конец последнего # добавленного, то мы расширяем записанный интервал до конца # текущего. В противном случае просто добавляем текущий интервал в # итоговый список интервалов. res = [intervals[0]] for i in range(1, len(intervals)): if res[-1][1] >= intervals[i][0]: res[-1][1] = max(intervals[i][1], res[-1][1]) else: res.append(intervals[i]) return res def normilize_intervals(intervals) -> list: """Разбивает полученный список на пары, расширяет интервалы, убирает вложенные интервалы.""" # из списка [1,2,3,4] формируем [[1,2], [3,4]] intervals_ = [intervals[i : i + 2] for i in range(0, len(intervals), 2)] # убираем вложенные интервалы n_intervals = absorb_small_included_intervals(intervals_) # расширяем пересекающиеся интервалы result = merge_intersected_intervals(n_intervals) return result