public static void Main()
const string fileName = "test.txt";
var conferenceManager = new ConferenceManager();
conferenceManager.ScheduleConference(fileName);
Console.WriteLine(e.Message);
using System.Collections.Generic;
public class ConferenceManager
public List<List<Talk>> ScheduleConference(string fileName)
List<string> talkList = GetTalkListFromFile(fileName);
return ScheduleConference(talkList);
public List<List<Talk>> ScheduleConference(List<String> talkList)
List<Talk> talksList = validateAndCreateTalks(talkList);
return GetScheduleConferenceTrack(talksList);
public List<string> GetTalkListFromFile(string fileName)
string[] linesInFile = File.ReadAllLines(fileName);
return linesInFile.ToList();
private List<Talk> validateAndCreateTalks(List<String> talkList)
Console.WriteLine("Empty Talk List");
List<Talk> validTalksList = new List<Talk>();
string minSuffix = "min";
string lightningSuffix = "lightning";
foreach (string talk in talkList)
int lastSpaceIndex = talk.LastIndexOf(" ");
if (lastSpaceIndex == -1)
Console.WriteLine("Invalid talk, " + talk + ". Talk time must be specify.");
string name = talk.Substring(0, lastSpaceIndex);
String timeStr = talk.Substring(lastSpaceIndex + 1);
if (name == null || "".Equals(name.Trim()))
Console.WriteLine("Invalid talk name, " + talk);
if (!timeStr.EndsWith(minSuffix) && !timeStr.EndsWith(lightningSuffix))
Console.WriteLine("Invalid talk time, " + talk + ". Time must be in min or in lightning");
if (timeStr.EndsWith(minSuffix))
time = Int32.Parse(timeStr.Substring(0, timeStr.IndexOf(minSuffix)));
else if (timeStr.EndsWith(lightningSuffix))
string lightningTime = timeStr.Substring(0, timeStr.IndexOf(lightningSuffix));
if ("".Equals(lightningTime))
time = Int32.Parse(lightningTime) * 5;
validTalksList.Add(new Talk(talk, name, time));
private List<List<Talk>> GetScheduleConferenceTrack(List<Talk> talksList)
int perDayMinTime = 6 * 60;
int totalTalksTime = GetTotalTalksTime(talksList);
int totalPossibleDays = totalTalksTime / perDayMinTime;
List<Talk> talksListForOperation = new List<Talk>();
talksListForOperation.AddRange(talksList);
var sortedTalk = talksListForOperation.OrderByDescending(e => e.timeDuration);
talksListForOperation = sortedTalk.ToList();
List<List<Talk>> combForMornSessions = FindPossibleCombSession(talksListForOperation, totalPossibleDays, true);
foreach (List<Talk> talkList in combForMornSessions)
var toRemove = new List<Talk>();
toRemove.AddRange(talkList);
talksListForOperation.RemoveAll(toRemove.Contains);
List<List<Talk>> combForEveSessions = FindPossibleCombSession(talksListForOperation, totalPossibleDays, false);
foreach (List<Talk> talkList in combForEveSessions)
var toRemove = new List<Talk>();
toRemove.AddRange(talkList);
talksListForOperation.RemoveAll(toRemove.Contains);
int maxSessionTimeLimit = 240;
if (talksListForOperation.Count != 0)
List<Talk> scheduledTalkList = new List<Talk>();
foreach (List<Talk> talkList in combForEveSessions)
int totalTime = GetTotalTalksTime(talkList);
foreach (Talk talk in talksListForOperation)
int talkTime = talk.getTimeDuration();
if (talkTime + totalTime <= maxSessionTimeLimit)
scheduledTalkList.Add(talk);
var toRemove = new List<Talk>();
toRemove.AddRange(talkList);
talksListForOperation.RemoveAll(toRemove.Contains);
if (talksListForOperation.Count == 0)
return GetScheduledTalksList(combForMornSessions, combForEveSessions);
private List<List<Talk>> FindPossibleCombSession(List<Talk> talksListForOperation, int totalPossibleDays, bool morningSession)
int minSessionTimeLimit = 180;
int maxSessionTimeLimit = 240;
maxSessionTimeLimit = minSessionTimeLimit;
int talkListSize = talksListForOperation.Count;
List<List<Talk>> possibleCombinationsOfTalks = new List<List<Talk>>();
int possibleCombinationCount = 0;
for (int count = 0; count < talkListSize; count++)
List<Talk> possibleCombinationList = new List<Talk>();
while (startPoint != talkListSize)
int currentCount = startPoint;
Talk currentTalk = talksListForOperation[currentCount];
if (currentTalk.isScheduled())
int talkTime = currentTalk.getTimeDuration();
if (talkTime > maxSessionTimeLimit || talkTime + totalTime > maxSessionTimeLimit)
possibleCombinationList.Add(currentTalk);
if (totalTime == maxSessionTimeLimit)
else if (totalTime >= minSessionTimeLimit)
bool validSession = false;
validSession = (totalTime == maxSessionTimeLimit);
validSession = (totalTime >= minSessionTimeLimit && totalTime <= maxSessionTimeLimit);
possibleCombinationsOfTalks.Add(possibleCombinationList);
foreach (Talk talk in possibleCombinationList)
possibleCombinationCount++;
if (possibleCombinationCount == totalPossibleDays)
return possibleCombinationsOfTalks;
private List<List<Talk>> GetScheduledTalksList(List<List<Talk>> combForMornSessions, List<List<Talk>> combForEveSessions)
List<List<Talk>> scheduledTalksList = new List<List<Talk>>();
int totalPossibleDays = combForMornSessions.Count;
for (int dayCount = 0; dayCount < totalPossibleDays; dayCount++)
List<Talk> talkList = new List<Talk>();
DateTime date = DateTime.Today.AddHours(9);
int trackCount = dayCount + 1;
string scheduledTime = date.ToString("hh:mmtt");
Console.WriteLine("Track " + trackCount + ":");
List<Talk> mornSessionTalkList = combForMornSessions[dayCount];
foreach (Talk talk in mornSessionTalkList)
talk.setScheduledTime(scheduledTime);
Console.WriteLine(scheduledTime + talk.getTitle());
scheduledTime = GetNextScheduledTime(date, talk.getTimeDuration());
int lunchTimeDuration = 60;
Talk lunchTalk = new Talk("Lunch", "Lunch", 60);
lunchTalk.setScheduledTime(scheduledTime);
Console.WriteLine(scheduledTime + "Lunch");
scheduledTime = GetNextScheduledTime(date, lunchTimeDuration);
List<Talk> eveSessionTalkList = combForEveSessions[dayCount];
foreach (Talk talk in eveSessionTalkList)
talk.setScheduledTime(scheduledTime);
Console.WriteLine(scheduledTime + talk.getTitle());
scheduledTime = GetNextScheduledTime(date, talk.getTimeDuration());
Talk networkingTalk = new Talk("Networking Event", "Networking Event", 60);
networkingTalk.setScheduledTime(scheduledTime);
talkList.Add(networkingTalk);
Console.WriteLine(scheduledTime + "Networking Event\n");
scheduledTalksList.Add(talkList);
return scheduledTalksList;
public static int GetTotalTalksTime(List<Talk> talksList)
if (talksList == null || talksList.Count == 0)
foreach (Talk talk in talksList)
totalTime += talk.timeDuration;
private string GetNextScheduledTime(DateTime date, int timeDuration)
long timeInLong = date.Minute;
long timeDurationInLong = timeDuration * 60 * 1000;
long newTimeInLong = timeInLong + timeDurationInLong;
var dates = date.AddMilliseconds(newTimeInLong);
string str = dates.ToString("hh:mmtt");
public bool scheduled = false;
public Talk(string title, string name, int time)
this.timeDuration = time;
public void setScheduled(bool scheduled)
this.scheduled = scheduled;
public bool isScheduled()
public void setScheduledTime(string scheduledTime)
this.scheduledTime = scheduledTime;
public string getScheduledTime()
public int getTimeDuration()
public int compareTo(Object obj)
if (timeDuration > talk.timeDuration)
if (timeDuration < talk.timeDuration)