Last active
May 21, 2021 00:41
-
-
Save rjrajivjha/5a717c84af830620382a68d7d1369dfb to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Given a list of existing meetings (each containing a meeting a set of participants, a room, start and end times) and an input (containing a room and a set of users) find out the possible times at which a meeting can be held with that room and users. | |
Meeting = start time and end time, room, set of participants (including owner) , | |
Room = 1 , users_set = (1, 2, 3) | |
Step 1 : | |
filter meeting for target room : O(n), : considering n meeting | |
set_of_time = list [list] | |
filter for users -> defaultdict(list) -> 0(n*u) : no. of target users -> u | |
return possible duration [ [start, end],[start, end],] | |
24 our working. | |
""" | |
import datetime | |
from collections import defaultdict | |
from typing import List | |
MINUTES_IN_DAY = 1440 | |
SECONDS_IN_MINUTE = 60 | |
MINUTES_IN_HOUR = 60 | |
class Meeting: | |
def __init__(self, start_time: datetime.datetime, end_time: datetime.datetime, room_num: int, participants: list): | |
self.start = start_time | |
self.end = end_time | |
self.room = room_num | |
self.participants = participants | |
def create_meetings(): | |
ml = [] | |
s = datetime.datetime(2021, 5, 20, 8, 0) | |
e = datetime.datetime(2021, 5, 20, 9, 0) | |
ml.append(Meeting(s, e, 1, [1, 4])) | |
s = datetime.datetime(2021, 5, 20, 8, 30) | |
e = datetime.datetime(2021, 5, 20, 9, 30) | |
ml.append(Meeting(s, e, 2, [2, 3])) | |
s = datetime.datetime(2021, 5, 20, 9, 30) | |
e = datetime.datetime(2021, 5, 20, 10, 15) | |
ml.append(Meeting(s, e, 1, [3, 4])) | |
s = datetime.datetime(2021, 5, 20, 10, 20) | |
e = datetime.datetime(2021, 5, 20, 12, 0) | |
ml.append(Meeting(s, e, 2, [1, 4])) | |
s = datetime.datetime(2021, 5, 20, 2, 0) | |
e = datetime.datetime(2021, 5, 20, 8, 0) | |
ml.append(Meeting(s, e, 1, [1, 2, 5, 4, 3])) | |
s = datetime.datetime(2021, 5, 20, 18, 0) | |
e = datetime.datetime(2021, 5, 21, 23, 0) | |
ml.append(Meeting(s, e, 1, [1, 2, 3, 4])) | |
return ml | |
def get_minute(date_time_object: datetime.datetime) -> int: | |
midnight = datetime.datetime.combine(date_time_object.date(), datetime.time()) | |
minute = (date_time_object - midnight).seconds // SECONDS_IN_MINUTE | |
return minute | |
def get_hour_min_back(minutes: int, given_date: datetime.date) -> datetime.datetime: | |
hour = minutes//MINUTES_IN_HOUR | |
minute = minutes % SECONDS_IN_MINUTE | |
time_in_dt_format = datetime.datetime.combine(given_date, datetime.time(hour, minute)) | |
return time_in_dt_format | |
def extract_slots_between_intervals(tmp: list, given_date: datetime.date) -> list: | |
available_slots = [] | |
i = 0 | |
for i in range(len(tmp) - 1): | |
available_slots.append([get_hour_min_back(tmp[i][1], given_date), get_hour_min_back(tmp[i + 1][0], given_date)]) | |
if tmp[i + 1][1] != 0 or tmp[i + 1][1] < MINUTES_IN_DAY: | |
available_slots.append([get_hour_min_back(tmp[i + 1][1], given_date), get_hour_min_back(0, given_date)]) | |
return available_slots | |
def merge_intervals(intervals): | |
temp = [] | |
while intervals: | |
time_range = intervals.pop() | |
if temp and temp[-1][1] >= time_range[0]: | |
temp[-1][1] = max(time_range[1], temp[-1][1]) | |
else: | |
temp.append(time_range) | |
return temp | |
def get_slots_from_busy_schedule(meeting_duration: list, given_date: datetime.date) -> list: | |
intervals = [list(x) for user in meeting_duration for x in user] | |
intervals.sort(key=lambda x: x[0], reverse=True) | |
temp = merge_intervals(intervals) | |
return extract_slots_between_intervals(temp, given_date) | |
def merge_participants_room_schedule(user_busy_time, room_busy_time, expected_participants): | |
for users, val in user_busy_time.items(): | |
user_busy_time[users] = sorted(val) | |
merged_schedule = [room_busy_time] | |
for participant in expected_participants: | |
merged_schedule.append(user_busy_time[participant]) | |
return merged_schedule | |
def get_busy_schedule(meetings_list, target_room, expected_participants): | |
user_busy_time = defaultdict(list) | |
room_busy_time = [] | |
for meet in meetings_list: | |
if meet.room == target_room: | |
li = [get_minute(meet.start), get_minute(meet.end)] | |
room_busy_time.append(li) | |
for participant in expected_participants: | |
if participant in meet.participants: | |
user_busy_time[participant].append([get_minute(meet.start), get_minute(meet.end)]) | |
return merge_participants_room_schedule(user_busy_time, room_busy_time, expected_participants) | |
def get_free_slots( | |
meetings_list: List[Meeting], target_room: int, expected_participants: list) -> List[datetime.datetime]: | |
given_date = meetings_list[0].start.date() | |
busy_schedule = get_busy_schedule(meetings_list, target_room, expected_participants) | |
return get_slots_from_busy_schedule(busy_schedule, given_date) | |
def main(): | |
meeting_list = create_meetings() | |
room_number = 1 | |
participants = [4, 5] | |
free_slots = get_free_slots(meeting_list, room_number, participants) | |
print(free_slots) | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment