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.
49 lines
1.8 KiB
49 lines
1.8 KiB
3 years ago
|
"""Модуль поиска пересечений интервалов."""
|
||
|
|
||
|
|
||
|
def has_intersection(interval_A, interval_B) -> bool:
|
||
|
"""Пересекаются ли интервалы."""
|
||
|
if interval_A[1] <= interval_B[0]:
|
||
|
return False
|
||
|
|
||
|
if interval_B[1] <= interval_A[0]:
|
||
|
return False
|
||
|
|
||
|
return True
|
||
|
|
||
|
|
||
|
def get_intersection(interval_A, interval_B) -> list:
|
||
|
"""Возвращает пересечение двух интервалов, если они не
|
||
|
пересекаются, возвращает пустой интервал."""
|
||
|
if not has_intersection(interval_A, interval_B):
|
||
|
return []
|
||
|
|
||
|
begin = max(interval_A[0], interval_B[0])
|
||
|
end = min(interval_A[1], interval_B[1])
|
||
|
|
||
|
return [begin, end]
|
||
|
|
||
|
|
||
|
def get_all_intersections(intervals_A, intervals_B) -> list:
|
||
|
"""Принимает два списка интервалов, для которых нужно найти
|
||
|
пересечения. Возвращает список найденных пересечений."""
|
||
|
|
||
|
# задаем индексы для каждого из интервалов
|
||
|
p_A, p_B = 0, 0
|
||
|
res = []
|
||
|
|
||
|
# Если текущий интервал в списке intervals_A заканчивается позже,
|
||
|
# чем текущий интервал в списке intervals_B, нам нужно перейти на
|
||
|
# следующий интервал в списке intervals_B. Таким образом по
|
||
|
# спискам мы пройдем всего лишь раз.
|
||
|
while p_A < len(intervals_A) and p_B < len(intervals_B):
|
||
|
A, B = intervals_A[p_A], intervals_B[p_B]
|
||
|
if has_intersection(A, B):
|
||
|
res.append(get_intersection(A, B))
|
||
|
|
||
|
if A[1] <= B[1]:
|
||
|
p_A += 1
|
||
|
else:
|
||
|
p_B += 1
|
||
|
return res
|