Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save rjrajivjha/5a717c84af830620382a68d7d1369dfb to your computer and use it in GitHub Desktop.
Save rjrajivjha/5a717c84af830620382a68d7d1369dfb to your computer and use it in GitHub Desktop.
"""
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