""" Question Stan is looking to provide access to creators' calendars and enable fans to book meetings with them. Your assignment is to create an algorythm that will assess creator's calendar and return available slots for fans to book. """ # TODO: add functionality for 30 minutes of precision def fetch_available_slots(duration, events): """ :param duration : duration of the slot we're trying to book in minutes :param events >>: list of start and end dates of time slots that are alrady taken i.e. [["2021-06-20 00:00AM", "2021-06-20 00:30AM"],["2021-06-20 11:00AM", "2021-06-20 11:30AM"], ["2021-06-20 03:00PM", "2021-06-20 04:00PM"] ] basically a tuple of [start, end] :return >>: list of slots a fan may book 24 hours * 60 min = 1440 """ # interpret what the day is # assume all day is "today" # TODO: error checking of inputs # sortedEvents = [] def timeSegment(duration, start,end): """ list of segments """ precision = 30 segments = [] if (start % precision) > 0: start += (precision - start % precision) if (end % precision) > 0: end -= end % precision timeCursor = start while(timeCursor + duration <= end): segments.append([timeCursor, timeCursor + duration]) timeCursor += duration return segments times = [] eventsLen = len(events) if eventsLen <= 0: return [] # sort by start times sortedEvents = sorted(events) # delete duplicates curr = sortedEvents[0] tempEvents = [curr] for i in sortedEvents: if curr[1] < i[1]: tempEvents.append(i) curr = i sortedEvents = tempEvents eventsLen = len(sortedEvents) # time between 0 to first start time # add to times array # if first starttime is not 0 and time between 0 and first starttime >= duration firstStartTime = sortedEvents[0][0] if firstStartTime > duration: # cut up into slots by duration resultTemp = timeSegment(duration, 0, firstStartTime) times += resultTemp # time between end time to start time of each # cut up into slots by duration # add to times array # could hvae been for -loop eventI = 0 while eventI < (eventsLen - 1): endTimeOne = sortedEvents[eventI][1] startTimeTwo = sortedEvents[eventI + 1][0] if (startTimeTwo - endTimeOne) > duration: resultTemp = timeSegment(duration, endTimeOne, startTimeTwo) times += resultTemp eventI += 1 # time between last end time to 1440 # cut up into slots by duration # add to times array lastEndTime = sortedEvents[eventsLen - 1][1] if lastEndTime < (1440 - duration): resultTemp = timeSegment(duration, lastEndTime, 1440) times += resultTemp return times result = fetch_available_slots(30,[[0, 30], [60, 120], [900, 960]]) # [] # all day available # [[15, 45], [60, 75]] # events ending on the edges may be tricky # [[365, 1300], [364, 369]] # one inside another # [[20, 30], [20, 100]] # two events same start date # [[100, 166], [150, 166]] # two events same end date # [[365, 1300], [500, 1100]] # one inside another # [[0, 30], [60, 120], [900, 960]], 90 min slot # falling in between events # [[0, 1440]] # all day busy # [[93, 277]] # weird times # [[1, 3]] # weird times print(result)