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.
48 lines
1.8 KiB
48 lines
1.8 KiB
"""Модуль поиска пересечений интервалов.""" |
|
|
|
|
|
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
|
|
|