using System; using System.Collections.Generic; using System.IO; using System.Linq; namespace D7._2 { class Steps : SortedDictionary> { } class Program { static void Main(string[] args) { if (args.Length < 1) return; if (File.Exists(args[0]) == false) return; var file = File.OpenText(args[0]); var steps = new Steps(); var builders = new (char task, int time)?[5]; int totalWorkTime = 0; do { var line = file.ReadLine(); if (line == null) break; AddDependency(steps, line); } while (true); do { // Assign tasks to available workers (char task, int time)? quickest = AssignWorkers(steps, builders); // Work assigned tasks if (quickest.HasValue == false) DumpData(steps, builders); else WorkIt(steps, builders, quickest.Value); totalWorkTime += quickest.Value.time; Console.WriteLine($"Total elapsed time : '{totalWorkTime}'"); } while (steps.Count > 0); Console.WriteLine($"===== ANSWER =========="); Console.WriteLine($"Total elapsed time : '{totalWorkTime}'"); } private static void WorkIt(Steps steps, (char task, int time)?[] builders, (char task, int time) quickest) { for (int i = 0; i < builders.Length; ++i) { if (builders[i].HasValue == false) continue; var builder = builders[i].Value; builder.time -= quickest.time; if (builder.time <= 0) { builders[i] = null; removeDependency(steps, quickest.task); Console.WriteLine($"Worker #{i} finnished task '{builder.task}'"); } else builders[i] = builder; } } private static (char task, int time)? AssignWorkers(Steps steps, (char task, int time)?[] builders) { (char task, int time)? quickest = null; for (int i = 0; i < builders.Length; ++i) { if (builders[i].HasValue == false) { (char task, int time)? taskN = getFirstTask(steps); if (taskN.HasValue == false) continue; var t = taskN.Value; steps.Remove(t.task); builders[i] = t; Console.WriteLine($"Assigned task '{t.task}' to worker #{i} (load : {t.time}s)"); } if (quickest.HasValue == false || builders[i].Value.time < quickest.Value.time) quickest = builders[i]; } return quickest; } static void removeDependency(Steps steps, char dep) { foreach (var step in steps) step.Value.Remove(dep); } static (char task, int time)? getFirstTask(Steps steps) { foreach (var step in steps) { if (step.Value.Count == 0) return (step.Key, (int)(step.Key - 'A' + 1) + 60); } return null; } static void AddDependency(IDictionary> steps, string line) { var left = line.Substring(5, 1)[0]; var right = line.Substring(36, 1)[0]; if (steps.ContainsKey(left) == false) steps.Add(left, new HashSet()); if (steps.ContainsKey(right) == false) steps.Add(right, new HashSet()); steps[right].Add(left); } // --------------------------------------------------------------------------------------- private static void DumpData(Steps steps, (char task, int time)?[] builders) { Console.WriteLine($"===== DUMP WORKERS =========="); for (int i = 0; i < builders.Length; ++i) { var builder = builders[i]; if (builder.HasValue) Console.WriteLine($"Worker #{i} state : Task '{builder.Value.task}', {builder.Value.time}s left"); else Console.WriteLine($"Worker #{i} state : VACANT"); } Console.WriteLine($"===== DUMP STEPS =========="); foreach (var step in steps) { Console.WriteLine($"Step '{step.Key}' state : {step.Value.Count} dependencies left"); } } } }