Browse Source

Рефакторинг в процессе

master
Дмитрий 3 years ago
parent
commit
b98fd26f8e
  1. 123
      task_3.py

123
task_3.py

@ -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

Loading…
Cancel
Save