.......... [100%] 10 passed in 0.01s score: 10/10 (100%)
__pycache__/ *.pyc .pytest_cache/
from .core import min_rooms, total_meeting_time __all__ = ["min_rooms", "total_meeting_time"]
"""Meeting-room scheduling helpers.
Meetings are half-open intervals ``[start, end)``: a room is occupied from ``start`` and becomes
free again exactly at ``end``. So ``[0, 10)`` and ``[10, 20)`` do not conflict and can share one
room, while ``[0, 10)`` and ``[5, 15)`` overlap and need two rooms.
"""
def _peak_concurrency(meetings):
"""Maximum number of meetings that are in progress at the same instant.
Implemented with a sweep over start/end events: a ``+1`` when a meeting starts and a ``-1``
when it ends. Because the intervals are half-open, at any shared timestamp a room is freed
(``-1``) *before* the next meeting takes one (``+1``).
"""
events = []
for start, end in meetings:
if end < start:
raise ValueError(f"meeting ends before it starts: {(start, end)}")
events.append((start, +1))
events.append((end, -1))
# Order events by time. On ties, an end must be processed before a start so a back-to-back
# meeting reuses the freed room instead of demanding a new one.
events.sort(key=lambda e: (e[0], e[1]))
current = peak = 0
for _, delta in events:
current += delta
if current > peak:
peak = current
return peak
def min_rooms(meetings):
"""Minimum number of rooms needed to host every meeting without a conflict."""
return _peak_concurrency(meetings)
def total_meeting_time(meetings):
"""Total scheduled time across all meetings (each meeting counted once)."""
return sum(end - start for start, end in meetings)
import os
import sys
# Make the package importable no matter what directory pytest is invoked from.
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from meetings import min_rooms, total_meeting_time
def test_total_meeting_time():
assert total_meeting_time([(0, 10), (30, 45)]) == 25
def test_overlapping_meetings_need_two_rooms():
assert min_rooms([(0, 30), (5, 10), (15, 20)]) == 2
def test_back_to_back_meetings_share_one_room():
# The first room frees exactly when the second meeting starts, so one room is enough.
assert min_rooms([(0, 10), (10, 20)]) == 1
.......... [100%] 10 passed in 0.01s score: 10/10 (100%)
__pycache__/ *.pyc .pytest_cache/
from .core import min_rooms, total_meeting_time __all__ = ["min_rooms", "total_meeting_time"]
"""Meeting-room scheduling helpers.
Meetings are half-open intervals ``[start, end)``: a room is occupied from ``start`` and becomes
free again exactly at ``end``. So ``[0, 10)`` and ``[10, 20)`` do not conflict and can share one
room, while ``[0, 10)`` and ``[5, 15)`` overlap and need two rooms.
"""
def _peak_concurrency(meetings):
"""Maximum number of meetings that are in progress at the same instant.
Implemented with a sweep over start/end events: a ``+1`` when a meeting starts and a ``-1``
when it ends. Because the intervals are half-open, at any shared timestamp a room is freed
(``-1``) *before* the next meeting takes one (``+1``).
"""
events = []
for start, end in meetings:
if end < start:
raise ValueError(f"meeting ends before it starts: {(start, end)}")
events.append((start, +1))
events.append((end, -1))
# Order events by time. On ties, an end must be processed before a start so a back-to-back
# meeting reuses the freed room instead of demanding a new one.
events.sort(key=lambda e: (e[0], e[1]))
current = peak = 0
for _, delta in events:
current += delta
if current > peak:
peak = current
return peak
def min_rooms(meetings):
"""Minimum number of rooms needed to host every meeting without a conflict."""
return _peak_concurrency(meetings)
def total_meeting_time(meetings):
"""Total scheduled time across all meetings (each meeting counted once)."""
return sum(end - start for start, end in meetings)
import os
import sys
# Make the package importable no matter what directory pytest is invoked from.
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from meetings import min_rooms, total_meeting_time
def test_total_meeting_time():
assert total_meeting_time([(0, 10), (30, 45)]) == 25
def test_overlapping_meetings_need_two_rooms():
assert min_rooms([(0, 30), (5, 10), (15, 20)]) == 2
def test_back_to_back_meetings_share_one_room():
# The first room frees exactly when the second meeting starts, so one room is enough.
assert min_rooms([(0, 10), (10, 20)]) == 1
.......... [100%] 10 passed in 0.01s score: 10/10 (100%)
__pycache__/ *.pyc .pytest_cache/
from .core import min_rooms, total_meeting_time __all__ = ["min_rooms", "total_meeting_time"]
"""Meeting-room scheduling helpers.
Meetings are half-open intervals ``[start, end)``: a room is occupied from ``start`` and becomes
free again exactly at ``end``. So ``[0, 10)`` and ``[10, 20)`` do not conflict and can share one
room, while ``[0, 10)`` and ``[5, 15)`` overlap and need two rooms.
"""
def _peak_concurrency(meetings):
"""Maximum number of meetings that are in progress at the same instant.
Implemented with a sweep over start/end events: a ``+1`` when a meeting starts and a ``-1``
when it ends. Because the intervals are half-open, at any shared timestamp a room is freed
(``-1``) *before* the next meeting takes one (``+1``).
"""
events = []
for start, end in meetings:
if end < start:
raise ValueError(f"meeting ends before it starts: {(start, end)}")
events.append((start, +1))
events.append((end, -1))
# Order events by time. On ties, an end must be processed before a start so a back-to-back
# meeting reuses the freed room instead of demanding a new one.
events.sort(key=lambda e: (e[0], e[1]))
current = peak = 0
for _, delta in events:
current += delta
if current > peak:
peak = current
return peak
def min_rooms(meetings):
"""Minimum number of rooms needed to host every meeting without a conflict."""
return _peak_concurrency(meetings)
def total_meeting_time(meetings):
"""Total scheduled time across all meetings (each meeting counted once)."""
return sum(end - start for start, end in meetings)
import os
import sys
# Make the package importable no matter what directory pytest is invoked from.
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from meetings import min_rooms, total_meeting_time
def test_total_meeting_time():
assert total_meeting_time([(0, 10), (30, 45)]) == 25
def test_overlapping_meetings_need_two_rooms():
assert min_rooms([(0, 30), (5, 10), (15, 20)]) == 2
def test_back_to_back_meetings_share_one_room():
# The first room frees exactly when the second meeting starts, so one room is enough.
assert min_rooms([(0, 10), (10, 20)]) == 1
.......... [100%] 10 passed in 0.01s score: 10/10 (100%)
__pycache__/ *.pyc .pytest_cache/ .session/
from .core import min_rooms, total_meeting_time __all__ = ["min_rooms", "total_meeting_time"]
"""Meeting-room scheduling helpers.
Meetings are half-open intervals ``[start, end)``: a room is occupied from ``start`` and becomes
free again exactly at ``end``. So ``[0, 10)`` and ``[10, 20)`` do not conflict and can share one
room, while ``[0, 10)`` and ``[5, 15)`` overlap and need two rooms.
"""
def _peak_concurrency(meetings):
"""Maximum number of meetings that are in progress at the same instant.
Implemented with a sweep over start/end events: a ``+1`` when a meeting starts and a ``-1``
when it ends. Because the intervals are half-open, at any shared timestamp a room is freed
(``-1``) *before* the next meeting takes one (``+1``).
"""
events = []
for start, end in meetings:
if end < start:
raise ValueError(f"meeting ends before it starts: {(start, end)}")
events.append((start, +1))
events.append((end, -1))
# Order events by time. On ties, an end must be processed before a start so a back-to-back
# meeting reuses the freed room instead of demanding a new one.
events.sort(key=lambda e: (e[0], e[1]))
current = peak = 0
for _, delta in events:
current += delta
if current > peak:
peak = current
return peak
def min_rooms(meetings):
"""Minimum number of rooms needed to host every meeting without a conflict."""
return _peak_concurrency(meetings)
def total_meeting_time(meetings):
"""Total scheduled time across all meetings (each meeting counted once)."""
return sum(end - start for start, end in meetings)
import os
import sys
# Make the package importable no matter what directory pytest is invoked from.
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from meetings import min_rooms, total_meeting_time
def test_total_meeting_time():
assert total_meeting_time([(0, 10), (30, 45)]) == 25
def test_overlapping_meetings_need_two_rooms():
assert min_rooms([(0, 30), (5, 10), (15, 20)]) == 2
def test_back_to_back_meetings_share_one_room():
# The first room frees exactly when the second meeting starts, so one room is enough.
assert min_rooms([(0, 10), (10, 20)]) == 1
.......... [100%] 10 passed in 0.01s score: 10/10 (100%)
__pycache__/ *.pyc .pytest_cache/
from .core import min_rooms, total_meeting_time __all__ = ["min_rooms", "total_meeting_time"]
"""Meeting-room scheduling helpers.
Meetings are half-open intervals ``[start, end)``: a room is occupied from ``start`` and becomes
free again exactly at ``end``. So ``[0, 10)`` and ``[10, 20)`` do not conflict and can share one
room, while ``[0, 10)`` and ``[5, 15)`` overlap and need two rooms.
"""
def _peak_concurrency(meetings):
"""Maximum number of meetings that are in progress at the same instant.
Implemented with a sweep over start/end events: a ``+1`` when a meeting starts and a ``-1``
when it ends. Because the intervals are half-open, at any shared timestamp a room is freed
(``-1``) *before* the next meeting takes one (``+1``).
"""
events = []
for start, end in meetings:
if end < start:
raise ValueError(f"meeting ends before it starts: {(start, end)}")
events.append((start, +1))
events.append((end, -1))
# Order events by time. On ties, an end must be processed before a start so a back-to-back
# meeting reuses the freed room instead of demanding a new one.
events.sort(key=lambda e: (e[0], e[1]))
current = peak = 0
for _, delta in events:
current += delta
if current > peak:
peak = current
return peak
def min_rooms(meetings):
"""Minimum number of rooms needed to host every meeting without a conflict."""
return _peak_concurrency(meetings)
def total_meeting_time(meetings):
"""Total scheduled time across all meetings (each meeting counted once)."""
return sum(end - start for start, end in meetings)
import os
import sys
# Make the package importable no matter what directory pytest is invoked from.
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from meetings import min_rooms, total_meeting_time
def test_total_meeting_time():
assert total_meeting_time([(0, 10), (30, 45)]) == 25
def test_overlapping_meetings_need_two_rooms():
assert min_rooms([(0, 30), (5, 10), (15, 20)]) == 2
def test_back_to_back_meetings_share_one_room():
# The first room frees exactly when the second meeting starts, so one room is enough.
assert min_rooms([(0, 10), (10, 20)]) == 1