private static IEnumerable <string> GetCalculationChain(IEnumerable <Cell> cells) { var topologicalSorter = new TopologicalSorter <string>(); foreach (var cell in cells) { var cellReferences = cell.Formula.Tokens.OfType <RefToken>().Select(x => x.CellReference) .Concat(cell.Formula.Tokens.OfType <AreaToken>().SelectMany(token => token.CellReferences)) .ToList(); if (!cellReferences.Any()) { continue; } topologicalSorter.Add(cell.Reference, cellReferences); } var(sorted, cycled) = topologicalSorter.Sort(); if (cycled.Any()) { throw new Exception("Cyclic dependencies"); } return(sorted); }
static void Main(string[] args) { List <Task> tasks = new List <Task> { new Task { Message = "A - depends on B and C" }, //0 new Task { Message = "B - depends on none" }, //1 new Task { Message = "C - depends on D and E" }, //2 new Task { Message = "D - depends on none" }, //3 new Task { Message = "E - depends on F, G and H" }, //4 new Task { Message = "F - depends on I" }, //5 new Task { Message = "G - depends on none" }, //6 new Task { Message = "H - depends on none" }, //7 new Task { Message = "I - depends on none" }, //8 }; TopologicalSorter <Task> resolver = new TopologicalSorter <Task>(); // now setting relations between them as described above resolver.Add(tasks[0], new[] { tasks[1], tasks[2] }); //resolver.Add(tasks[1]); // no need for this since the task was already mentioned as a dependency resolver.Add(tasks[2], new[] { tasks[3], tasks[4] }); //resolver.Add(tasks[3]); // no need for this since the task was already mentioned as a dependency resolver.Add(tasks[4], tasks[5], tasks[6], tasks[7]); resolver.Add(tasks[5], tasks[8]); //resolver.Add(tasks[6]); // no need for this since the task was already mentioned as a dependency //resolver.Add(tasks[7]); // no need for this since the task was already mentioned as a dependency //resolver.Add(tasks[3], tasks[0]); // uncomment this line to test cycled dependency var result = resolver.Sort(); var sorted = result.Item1; var cycled = result.Item2; if (!cycled.Any()) { foreach (var d in sorted) { Console.WriteLine(d.Message); } } else { Console.Write("Cycled dependencies detected: "); foreach (var d in cycled) { Console.Write($"{d.Message[0]} "); } Console.WriteLine(); } Console.WriteLine("exiting..."); }