public static void TaskSchedulerUtil(string[] tasks, List <string> tasksCovered, Dictionary <string, int> charFrequency, Dictionary <string, int> addTasksForIdle, Dictionary <string, int> charFreAux, int taskCompletedCount, int n) { // keep doing this until all tasks ae completed if (taskCompletedCount == tasks.Length) { return; } myTask removeTask = new myTask(); // if I can use c# PriorityQueue from C# 10.0 over here it would be helpful to reduce this sorting of O(n log n) charFrequency = charFrequency.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value); var pair = charFrequency.FirstOrDefault(x => x.Value > 0); if (pair.Key == null) { tasksCovered.Add("idle"); } else { removeTask.name = pair.Key; removeTask.frequency = pair.Value; removeTask.frequency--; charFrequency[removeTask.name] = -1; // marking it as -1, making it as good as removed for this problem. Since modifying collections gives runtime exception when running loop tasksCovered.Add(removeTask.name); charFreAux[removeTask.name] = removeTask.frequency; // keep the removed task data here before adding it back on after timer for that task is over taskCompletedCount++; } // for every task that was removed for main dictionary/queue keep the timer decreasing, so they can be added when timer is zero foreach (var key in addTasksForIdle.Keys.ToList()) { if (addTasksForIdle[key] == 0) { charFrequency[key] = charFreAux[key]; } addTasksForIdle[key] = addTasksForIdle[key] - 1; } // if there was a task done (not "idle") then removed task needs to be added in the timer/idle dictionary counter if (removeTask.name != null) { addTasksForIdle[removeTask.name] = n - 1; } TaskSchedulerUtil(tasks, tasksCovered, charFrequency, addTasksForIdle, charFreAux, taskCompletedCount, n); }
public static int TaskScheduler(string[] tasks, int n) { if (n == 0 || tasks.Length == 0) { return(tasks.Length); } int taskCompletedCount = 0; List <string> tasksCovered = new List <string>(); Dictionary <string, int> charFrequency = new Dictionary <string, int>(); // maintain chars and the frequency Dictionary <string, int> addTasksForIdle = new Dictionary <string, int>(); // maintain chars and the required idle time before adding the char back in charFrequency Dictionary <string, int> charFreAux = new Dictionary <string, int>(); // maintain chars and the frequency on the side while char was removed (set to -1) in charFrequency foreach (var task in tasks) { if (charFrequency.TryGetValue(task, out var fre)) { charFrequency[task] = fre + 1; } else { charFrequency.Add(task, 1); } addTasksForIdle[task] = -1; charFreAux[task] = -1; } myTask removeTask = new myTask(); // if I can use c# PriorityQueue from C# 10.0 over here it would be helpful to reduce this sorting of O(n log n) charFrequency = charFrequency.OrderByDescending(x => x.Value).ToDictionary(x => x.Key, x => x.Value); var pair = charFrequency.FirstOrDefault(x => x.Value > 0); removeTask.name = pair.Key; removeTask.frequency = pair.Value; removeTask.frequency--; charFrequency[removeTask.name] = -1; // marking it as -1, making it as good as removed for this problem. Since modifying collections gives runtime exception when running loop tasksCovered.Add(removeTask.name); charFreAux[removeTask.name] = removeTask.frequency; // keep the removed task data here before adding it back on after timer for that task is over addTasksForIdle[removeTask.name] = n - 1; TaskSchedulerUtil(tasks, tasksCovered, charFrequency, addTasksForIdle, charFreAux, ++taskCompletedCount, n); return(tasksCovered.Count()); }