Skip to content

Instantly share code, notes, and snippets.

@goatandsheep
Last active March 8, 2023 20:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save goatandsheep/e0905ffe143b7f0ce8c4f842929de072 to your computer and use it in GitHub Desktop.
Save goatandsheep/e0905ffe143b7f0ce8c4f842929de072 to your computer and use it in GitHub Desktop.
"""
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 <int>: duration of the slot we're trying to book in minutes
:param events <list<list<datetime>>>: 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<list<datetime>>>: 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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment