Тестовое задание
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

68 lines
3.4 KiB

"""Модуль, содержащий функции для чистки интервалов.
Под 'чисткой' подразумевается:
- удаление меньших интервалов, полностью входящих в большие (поглощение)
- расширение пересекающихся интервалов (сумма интервалов)
"""
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