public List<List<ExportLecture>> divideToGroups(List<ExportLecture> lectures)
{
List<List<ExportLecture>> groups = new List<List<ExportLecture>>();
groups.Add(new List<ExportLecture>());
foreach (ExportLecture l in lectures)
{
var lastgroup = groups[groups.Count - 1];
if (lastgroup.Count < 1)
{
groups[groups.Count - 1].Add(l);
}
//Is lecture l starting sooner than end time of the last lecture in last group (with 10 minutes toleration)?
else if (DateTime.Compare(l.StartTime, lastgroup.Max(lec => lec.StartTime + lec.Length - new TimeSpan(0, 10, 0))) < 0
&& l.Day == lastgroup[lastgroup.Count - 1].Day)
{
//All lectures intersecting with l
IEnumerable<ExportLecture> intersecting = lastgroup.Where(lec => (DateTime.Compare(l.StartTime, lec.StartTime + lec.Length - new TimeSpan(0, 10, 0)) < 0));
//Only have to worry about 3 and more lectures in one group
//If lecture l is intersecting with all of lectures in lastgroup then it belongs to the group
if (lastgroup.Count <= 1 || intersecting.Count() == lastgroup.Count)
{
lastgroup.Add(l);
}
//Otherwise create a new group with fake lectures
else
{
List<ExportLecture> newGroup = new List<ExportLecture>();
//Fake lectures from all last group lectures
foreach (ExportLecture lastGroupLec in lastgroup)
{
ExportLecture fakeLecture = null;
//Treat intersecting lectures as not null
if (intersecting.Contains(lastGroupLec))
{
fakeLecture = new ExportLecture(null, lastGroupLec.Day, lastGroupLec.StartTime, lastGroupLec.Length, null, null, null, true);
}
//Non-intersecting lecture are null = empty slots
newGroup.Add(fakeLecture);
}
//Find first empty slot in newGroup (null lecture) and swap with lecture l
int index = newGroup.FindIndex(lecture => lecture == null);
newGroup[index] = l;
//Finally remove all empty slots and add the newGroup to the groups
newGroup.RemoveAll(lecture => lecture == null);
groups.Add(newGroup);
lastgroup = newGroup;
}
}
else
{
groups.Add(new List<ExportLecture>());
lastgroup = groups[groups.Count - 1];
lastgroup.Add(l);
}
}
return groups;
}