using System.Collections.Generic;
using System.Threading.Tasks;
public class GetLongestSlot
public static void Main(string[] args)
Console.WriteLine("Format is HH:mm::ss");
var cal = new MyCalendar();
cal.ProcessMeeting(GetSlot(new TimeSpan(6,30,0), new TimeSpan(12, 30, 0)));
Console.WriteLine(cal.GetLongestFreeSlot());
cal.ProcessMeeting(GetSlot(new TimeSpan(23, 0, 0), new TimeSpan(23, 30, 0)));
Console.WriteLine(cal.GetLongestFreeSlot());
cal.ProcessMeeting(GetSlot(new TimeSpan(06, 0, 0), new TimeSpan(13, 0, 0)));
Console.WriteLine(cal.GetLongestFreeSlot());
cal.ProcessMeeting(GetSlot(new TimeSpan(16, 0, 0), new TimeSpan(18, 0, 0)));
Console.WriteLine(cal.GetLongestFreeSlot());
cal.ProcessMeeting(GetSlot(new TimeSpan(3, 0, 0), new TimeSpan(6, 0, 0)));
Console.WriteLine(cal.GetLongestFreeSlot());
cal.ProcessMeeting(GetSlot(0, 23));
Console.WriteLine(cal.GetLongestFreeSlot());
public static Slot GetSlot(int startHour, int endHour)
return new Slot(MyCalendar.GetStartOfDay().AddHours(startHour),
MyCalendar.GetStartOfDay().AddHours(endHour));
public static Slot GetSlot(TimeSpan startSpan, TimeSpan endSpan)
return new Slot(MyCalendar.GetStartOfDay().Add(startSpan),
MyCalendar.GetStartOfDay().Add(endSpan));
public void ProcessMeeting(Slot meetingSlot)
Console.WriteLine("Adding "+meetingSlot.start.Hour+":"+meetingSlot.start.Minute+":"+meetingSlot.start.Second +
" to " +meetingSlot.end.Hour+":"+meetingSlot.end.Minute+":"+meetingSlot.end.Second);
root.value = meetingSlot;
root.LeftLongestFree = new Slot(GetStartOfDay(), meetingSlot.start);
root.RightLongestFree = new Slot(meetingSlot.end, GetEndOfDay());
AddMeeting(root, meetingSlot, GetStartOfDay(), GetEndOfDay());
private Node CreateNode(Slot meetingSlot, DateTime leftMost, DateTime rightMost)
node.value = meetingSlot;
node.LeftLongestFree = new Slot(leftMost, meetingSlot.start);
node.RightLongestFree = new Slot(meetingSlot.end, rightMost);
if (node.value.start >= meetingSlot.end)
AddMeeting(node.left, meetingSlot, leftMost, node.value.start);
node.left = CreateNode(meetingSlot, leftMost, node.value.start);
node.LeftLongestFree = node.left.GetLongestFree();
else if (node.value.end <= meetingSlot.start)
AddMeeting(node.right, meetingSlot, node.value.end, rightMost);
node.right = CreateNode(meetingSlot, node.value.end, rightMost);
node.RightLongestFree = node.right.GetLongestFree();
if (meetingSlot.start < node.value.start)
splitMeeting = new Slot(meetingSlot.start, node.value.start);
AddMeeting(node, splitMeeting, leftMost, rightMost );
if ( meetingSlot.end > node.value.end)
splitMeeting = new Slot(node.value.end, meetingSlot.end);
AddMeeting(node, splitMeeting, leftMost, rightMost);
public Slot GetLongestFreeSlot()
return new Slot(GetStartOfDay(), GetEndOfDay());
return root.GetLongestFree();
public static DateTime GetStartOfDay()
return new DateTime(2019, 01, 10);
public static DateTime GetEndOfDay()
return new DateTime(2019, 01, 10).AddDays(1).AddTicks(-1);
public Slot LeftLongestFree;
public Slot RightLongestFree;
public Slot GetLongestFree()
if (LeftLongestFree.GetLength() > RightLongestFree.GetLength())
public TimeSpan GetLength()
public Slot(DateTime start, DateTime end)
public override string ToString()
return "\t LongestInterval start:"+start.Hour+":"+start.Minute+":"+start.Second+
" end:"+end.Hour+":"+end.Minute+":"+end.Second +