|
|
@ -83,9 +83,10 @@ def get_smaller_interval(interval_A, interval_B) -> list: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def absorb_small_included_intervals(intervals: list) -> list: |
|
|
|
def absorb_small_included_intervals(intervals: list) -> list: |
|
|
|
"""Если в списке есть вложенные интервалы (интревал меньшего |
|
|
|
"""Возвращает список интервалов без вложенных интервалов. |
|
|
|
размера, полностью входящий в больший), то убирает их и возвращает |
|
|
|
|
|
|
|
список без них. |
|
|
|
Вложенный интервал - интервал меньшего размера, полностью входящий |
|
|
|
|
|
|
|
в больший. |
|
|
|
|
|
|
|
|
|
|
|
Стоит учитывать, что функция работает только если интервалы |
|
|
|
Стоит учитывать, что функция работает только если интервалы |
|
|
|
совпадают по началу или концу, если интервалы входят друг в друга |
|
|
|
совпадают по началу или концу, если интервалы входят друг в друга |
|
|
@ -100,17 +101,14 @@ def absorb_small_included_intervals(intervals: list) -> list: |
|
|
|
if get_smaller_interval(interval, intervals[k]) |
|
|
|
if get_smaller_interval(interval, intervals[k]) |
|
|
|
] |
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
print(f"{small_intervals=}") |
|
|
|
|
|
|
|
result = [i for i in intervals if i not in small_intervals] |
|
|
|
result = [i for i in intervals if i not in small_intervals] |
|
|
|
print(f"{result=}") |
|
|
|
|
|
|
|
print(f"{intervals=}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return result |
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def extend_partial_included_intervals(interval_A, interval_B) -> list: |
|
|
|
def get_union_of_partly_intersecting_intervals(interval_A, interval_B) -> list: |
|
|
|
"""Если интервалы пересекаются, то мы заменяем их на сумму |
|
|
|
"""Если интервалы А и Б пересекаются, то возвращаем новый |
|
|
|
перескающихся интервалов.""" |
|
|
|
интервал, включающий А и Б.""" |
|
|
|
# планирую поступать по тому же принципу что и выше: добавлять |
|
|
|
# планирую поступать по тому же принципу что и выше: добавлять |
|
|
|
# сумму в исходный список, итого получим список с пересечениями, |
|
|
|
# сумму в исходный список, итого получим список с пересечениями, |
|
|
|
# который потом можно прогнать через поглатитель меньших |
|
|
|
# который потом можно прогнать через поглатитель меньших |
|
|
@ -132,66 +130,26 @@ def extend_partial_included_intervals(interval_A, interval_B) -> list: |
|
|
|
return [] |
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
# сумма интервалов: наименьшее начало из А и Б, и наибольший конец |
|
|
|
# сумма интервалов: наименьшее начало из А и Б, и наибольший конец |
|
|
|
|
|
|
|
# из А и Б |
|
|
|
interval_begin = min(interval_A[0], interval_B[0]) |
|
|
|
interval_begin = min(interval_A[0], interval_B[0]) |
|
|
|
interval_end = max(interval_A[1], interval_B[1]) |
|
|
|
interval_end = max(interval_A[1], interval_B[1]) |
|
|
|
print(f"get: {[interval_A, interval_B]}") |
|
|
|
|
|
|
|
print(f"res: {[interval_begin, interval_end]}") |
|
|
|
|
|
|
|
return [interval_begin, interval_end] |
|
|
|
return [interval_begin, interval_end] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def extend_intervals(intervals) -> list: |
|
|
|
def get_extended_intervals(intervals) -> list: |
|
|
|
|
|
|
|
"""Возвращает расширенные интервалы из списка интервалов.""" |
|
|
|
extended_intervals = [ |
|
|
|
extended_intervals = [ |
|
|
|
extend_partial_included_intervals(interval, intervals[k]) |
|
|
|
get_union_of_partly_intersecting_intervals(interval, intervals[k]) |
|
|
|
for i, interval in enumerate(intervals) |
|
|
|
for i, interval in enumerate(intervals) |
|
|
|
for k in range(i + 1, len(intervals)) |
|
|
|
for k in range(i + 1, len(intervals)) |
|
|
|
if extend_partial_included_intervals(interval, intervals[k]) |
|
|
|
if get_union_of_partly_intersecting_intervals(interval, intervals[k]) |
|
|
|
] |
|
|
|
] |
|
|
|
print(f"{extended_intervals=}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uniq_extended_intervals = [i for i in extended_intervals if i not in intervals] |
|
|
|
uniq_extended_intervals = [i for i in extended_intervals if i not in intervals] |
|
|
|
print(f"{uniq_extended_intervals=}") |
|
|
|
return uniq_extended_intervals |
|
|
|
|
|
|
|
|
|
|
|
result = intervals + uniq_extended_intervals |
|
|
|
|
|
|
|
result = absorb_small_included_intervals(result) |
|
|
|
|
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def find_inner_sum_of_intersections(interval_A, interval_B) -> list: |
|
|
|
|
|
|
|
print(f"{interval_A=}") |
|
|
|
|
|
|
|
print(f"{interval_B=}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# проверить, может быт интервалы входят друг в друга, и тогда |
|
|
|
|
|
|
|
# возвращаем больший |
|
|
|
|
|
|
|
if interval_A[0] < interval_B[0] and interval_A[1] > interval_B[1]: |
|
|
|
|
|
|
|
return interval_A |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if interval_B[0] < interval_A[0] and interval_B[1] > interval_A[1]: |
|
|
|
|
|
|
|
return interval_B |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if interval_A[0] == interval_B[0] and interval_A[1] == interval_B[1]: |
|
|
|
|
|
|
|
return [] |
|
|
|
|
|
|
|
# если один из интервалов пустой, то пересечение будет пустым |
|
|
|
|
|
|
|
if not interval_A or not interval_B: |
|
|
|
|
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# если какой-то из инетрвалов имеет нулевую длину (начало=конец), |
|
|
|
|
|
|
|
# то пересечение пустое |
|
|
|
|
|
|
|
if interval_A[0] == interval_A[1] or interval_B[0] == interval_B[1]: |
|
|
|
|
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# нужно проверить, что интервалы вообще пересекаются |
|
|
|
|
|
|
|
# А и B не пересекаются, если |
|
|
|
|
|
|
|
# начало А > конец B, или если начало B > конец А |
|
|
|
|
|
|
|
if interval_A[0] > interval_B[1] or interval_B[0] > interval_A[1]: |
|
|
|
|
|
|
|
return [] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# ищем сумму, а не пересечение |
|
|
|
|
|
|
|
interval_begin = min(interval_A[0], interval_B[0]) |
|
|
|
|
|
|
|
interval_end = max(interval_A[1], interval_B[1]) |
|
|
|
|
|
|
|
return [interval_begin, interval_end] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def find_intersection(interval_A, interval_B) -> list: |
|
|
|
def get_intersection(interval_A, interval_B) -> list: |
|
|
|
# если один из интервалов пустой, то пересечение будет пустым |
|
|
|
# если один из интервалов пустой, то пересечение будет пустым |
|
|
|
if not interval_A or not interval_B: |
|
|
|
if not interval_A or not interval_B: |
|
|
|
return [] |
|
|
|
return [] |
|
|
@ -214,65 +172,40 @@ def find_intersection(interval_A, interval_B) -> list: |
|
|
|
return [interval_begin, interval_end] |
|
|
|
return [interval_begin, interval_end] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def enlarge_elapsed_intervals(intervals): |
|
|
|
def normilize_intervals(intervals) -> list: |
|
|
|
# ключ - начало, значние - конец. Если по ключу "начало" уже есть |
|
|
|
"""Разбивает полученный список на пары, расширяет интервалы, |
|
|
|
# значение, то сохраняем max(существующее, новое) |
|
|
|
убирает вложенные интервалы.""" |
|
|
|
|
|
|
|
|
|
|
|
# чистка конечных интервалов. ключ в словаре - начало интервала. |
|
|
|
# из списка [1,2,3,4] формируем [[1,2], [3,4]] |
|
|
|
# проходим по исходному списку и выбираем наибольшее конечное |
|
|
|
intervals_ = [intervals[i : i + 2] for i in range(0, len(intervals), 2)] |
|
|
|
# значение (самый поздний) из интервалов с одинаковыми началами |
|
|
|
|
|
|
|
beginnings = {interval[0]: interval[1] for interval in intervals} |
|
|
|
|
|
|
|
for interval in intervals: |
|
|
|
|
|
|
|
begin = interval[0] |
|
|
|
|
|
|
|
end = interval[1] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
beginnings[begin] = max(beginnings[begin], end) |
|
|
|
# получаем расширенные интервалы |
|
|
|
print(f"{beginnings=}") |
|
|
|
extended_intervals = get_extended_intervals(intervals_) |
|
|
|
|
|
|
|
|
|
|
|
endings = {beginnings[k]: k for k in beginnings} |
|
|
|
# убираем вложенные инетрвалы |
|
|
|
for interval in intervals: |
|
|
|
n_intervals = absorb_small_included_intervals(intervals_ + extended_intervals) |
|
|
|
begin = interval[0] |
|
|
|
return n_intervals |
|
|
|
end = interval[1] |
|
|
|
|
|
|
|
if endings.get(end): |
|
|
|
|
|
|
|
endings[end] = min(endings[end], begin) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(f"{endings=}") |
|
|
|
|
|
|
|
result = [[endings[k], k] for k in endings] |
|
|
|
|
|
|
|
return result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def appearance(intervals): |
|
|
|
def appearance(intervals): |
|
|
|
lesson = intervals["lesson"] |
|
|
|
lesson = intervals["lesson"] |
|
|
|
tutor = [ |
|
|
|
pupil = normilize_intervals(intervals["pupil"]) |
|
|
|
intervals["tutor"][i : i + 2] for i in range(0, len(intervals["tutor"]), 2) |
|
|
|
tutor = normilize_intervals(intervals["tutor"]) |
|
|
|
] |
|
|
|
|
|
|
|
pupil = [ |
|
|
|
|
|
|
|
intervals["pupil"][i : i + 2] for i in range(0, len(intervals["pupil"]), 2) |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pupil = extend_intervals(pupil) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print(f"!!!{pupil=}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tutor = enlarge_elapsed_intervals(tutor) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# получаем все интервалы студента на уроке |
|
|
|
# получаем все интервалы студента на уроке |
|
|
|
pupil_on_lesson = [ |
|
|
|
pupil_on_lesson = [ |
|
|
|
find_intersection(lesson, p) for p in pupil if find_intersection(lesson, p) |
|
|
|
get_intersection(lesson, p) for p in pupil if get_intersection(lesson, p) |
|
|
|
] |
|
|
|
] |
|
|
|
print(f"{pupil_on_lesson=}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# по очереди сравниваем каждый из интервалов преподавателя с |
|
|
|
# по очереди сравниваем каждый из интервалов преподавателя с |
|
|
|
# каждым из интервалов пересечения студента на уроке |
|
|
|
# каждым из интервалов пересечения студента на уроке |
|
|
|
tutor_on_pupil = [ |
|
|
|
tutor_on_pupil = [ |
|
|
|
find_intersection(pol, t) for t in tutor for pol in pupil_on_lesson |
|
|
|
get_intersection(pol, t) for t in tutor for pol in pupil_on_lesson |
|
|
|
] |
|
|
|
] |
|
|
|
print(f"{tutor_on_pupil=}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# создаем список из продолжительности каждого интервала, если он |
|
|
|
# создаем список из продолжительности каждого интервала, если он |
|
|
|
# не пустой, а затем суммируем все элементы |
|
|
|
# не пустой, а затем суммируем все элементы |
|
|
|
answer = sum([intr[1] - intr[0] for intr in tutor_on_pupil if intr]) |
|
|
|
answer = sum([intr[1] - intr[0] for intr in tutor_on_pupil if intr]) |
|
|
|
print("----------------------------------------") |
|
|
|
|
|
|
|
return answer |
|
|
|
return answer |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|