public static IList <IEnumerable <T> > GetShortestSequences <T>(T start, T end, IList <Func <T, T> > functions) where T : IComparable <T> { var results = new List <IEnumerable <T> >(); var visited = new HashSet <T>(); var currentNodes = new Queue <Node <T> >(); visited.Add(start); currentNodes.Enqueue(new Node <T>(start)); while (currentNodes.Count > 0) { var nextNodes = new Queue <Node <T> >(); var nextVisited = new HashSet <T>(); while (currentNodes.Count > 0) { var currentNode = currentNodes.Dequeue(); foreach (var function in functions) { T nextElement = function(currentNode.Value); if (nextElement.CompareTo(end) > 0) { continue; } if (visited.Contains(nextElement)) { continue; } var nextNode = new Node <T>(nextElement); nextNode.Previous = currentNode; nextVisited.Add(nextElement); nextNodes.Enqueue(nextNode); if (nextElement.Equals(end)) { var sequence = new ReversedLinkedList <T>(nextNode); results.Add(sequence.Reverse()); } } } visited.UnionWith(nextVisited); if (results.Count != 0) { nextNodes.Clear(); } currentNodes = nextNodes; } return(results); }
static IList <IEnumerable <T> > GetShortestSequences <T>(T start, T end, IList <Func <T, T> > operations) where T : IComparable <T> { var results = new List <IEnumerable <T> >(); var visited = new HashSet <T>(); var currentWave = new Queue <Node <T> >(); visited.Add(start); currentWave.Enqueue(new Node <T>(start)); int level = 1; while (currentWave.Count != 0) { var nextWave = new Queue <Node <T> >(); var nextVisited = new HashSet <T>(); level++; while (currentWave.Count != 0) { var currentNode = currentWave.Dequeue(); foreach (var operation in operations) { T nextElement = operation(currentNode.Value); if (nextElement.CompareTo(end) > 0) { continue; } if (visited.Contains(nextElement)) { continue; } var nextNode = new Node <T>(nextElement); nextNode.Previous = currentNode; nextVisited.Add(nextElement); nextWave.Enqueue(nextNode); if (nextElement.Equals(end)) { var sequence = new ReversedLinkedList <T>(nextNode); results.Add(sequence.Reverse()); } } } visited.UnionWith(nextVisited); if (results.Count != 0) { nextWave.Clear(); } currentWave = nextWave; } //Console.WriteLine("Sequences length: {0}.", level); return(results); }