Whitespace, tidying

This commit is contained in:
Chris Cameron
2018-01-02 14:20:52 -05:00
parent 02cae250a6
commit d1b87cc329

View File

@@ -7,199 +7,212 @@ using ICD.Common.Utils.Extensions;
namespace ICD.Common.Utils namespace ICD.Common.Utils
{ {
public static class RecursionUtils public static class RecursionUtils
{ {
/// <summary> /// <summary>
/// Returns all of the nodes in the tree via breadth-first search. /// Returns all of the nodes in the tree via breadth-first search.
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="root"></param> /// <param name="root"></param>
/// <param name="getChildren"></param> /// <param name="getChildren"></param>
/// <returns></returns> /// <returns></returns>
public static IEnumerable<T> BreadthFirstSearch<T>(T root, Func<T, IEnumerable<T>> getChildren) public static IEnumerable<T> BreadthFirstSearch<T>(T root, Func<T, IEnumerable<T>> getChildren)
{ {
if (getChildren == null) if (getChildren == null)
throw new ArgumentNullException("getChildren"); throw new ArgumentNullException("getChildren");
Queue<T> process = new Queue<T>(); Queue<T> process = new Queue<T>();
process.Enqueue(root); process.Enqueue(root);
while (process.Count > 0) while (process.Count > 0)
{ {
T current = process.Dequeue(); T current = process.Dequeue();
yield return current; yield return current;
foreach (T child in getChildren(current)) foreach (T child in getChildren(current))
process.Enqueue(child); process.Enqueue(child);
} }
} }
/// <summary> /// <summary>
/// Returns the shortest path from root to destination via breadth-first search. /// Returns the shortest path from root to destination via breadth-first search.
/// </summary> /// </summary>
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <param name="root"></param> /// <param name="root"></param>
/// <param name="destination"></param> /// <param name="destination"></param>
/// <param name="getChildren"></param> /// <param name="getChildren"></param>
/// <returns></returns> /// <returns></returns>
[CanBeNull] [CanBeNull]
public static IEnumerable<T> BreadthFirstSearchPath<T>(T root, T destination, Func<T, IEnumerable<T>> getChildren) public static IEnumerable<T> BreadthFirstSearchPath<T>(T root, T destination, Func<T, IEnumerable<T>> getChildren)
{ {
if (getChildren == null) if (getChildren == null)
throw new ArgumentNullException("getChildren"); throw new ArgumentNullException("getChildren");
return BreadthFirstSearchPath(root, destination, getChildren, EqualityComparer<T>.Default); return BreadthFirstSearchPath(root, destination, getChildren, EqualityComparer<T>.Default);
} }
[NotNull] /// <summary>
public static Dictionary<T2, IEnumerable<T>> BreadthFirstSearchManyDestinations<T, T2>(T root, Dictionary<T2, T> destinations, Func<T, IEnumerable<T>> getChildren) /// Returns the shortest path from root to destination via breadth-first search.
{ /// </summary>
if (getChildren == null) /// <typeparam name="T"></typeparam>
throw new ArgumentNullException("getChildren"); /// <param name="root"></param>
/// <param name="destination"></param>
/// <param name="getChildren"></param>
/// <param name="comparer"></param>
/// <returns></returns>
[CanBeNull]
public static IEnumerable<T> BreadthFirstSearchPath<T>(T root, T destination, Func<T, IEnumerable<T>> getChildren,
IEqualityComparer<T> comparer)
{
if (getChildren == null)
throw new ArgumentNullException("getChildren");
return BreadthFirstSearchPathManyDestinations(root, destinations, getChildren, EqualityComparer<T>.Default); if (comparer == null)
} throw new ArgumentNullException("comparer");
/// <summary> // Edge case - root and destination are the same
/// Returns the shortest path from root to destination via breadth-first search. if (comparer.Equals(root, destination))
/// </summary> return new[] {root};
/// <typeparam name="T"></typeparam>
/// <param name="root"></param>
/// <param name="destination"></param>
/// <param name="getChildren"></param>
/// <param name="comparer"></param>
/// <returns></returns>
[CanBeNull]
public static IEnumerable<T> BreadthFirstSearchPath<T>(T root, T destination, Func<T, IEnumerable<T>> getChildren,
IEqualityComparer<T> comparer)
{
if (getChildren == null)
throw new ArgumentNullException("getChildren");
if (comparer == null) Queue<T> queue = new Queue<T>();
throw new ArgumentNullException("comparer"); queue.Enqueue(root);
// Edge case - root and destination are the same Dictionary<T, T> nodeParents = new Dictionary<T, T>();
if (comparer.Equals(root, destination))
return new[] { root };
Queue<T> queue = new Queue<T>(); while (queue.Count > 0)
queue.Enqueue(root); {
T current = queue.Dequeue();
Dictionary<T, T> nodeParents = new Dictionary<T, T>(); foreach (T node in getChildren(current))
{
if (nodeParents.ContainsKey(node))
continue;
while (queue.Count > 0) queue.Enqueue(node);
{ nodeParents.Add(node, current);
T current = queue.Dequeue();
foreach (T node in getChildren(current)) // Found a path to the destination
{ if (comparer.Equals(node, destination))
if (nodeParents.ContainsKey(node)) return GetPath(destination, nodeParents).Reverse();
continue; }
}
queue.Enqueue(node); return null;
nodeParents.Add(node, current); }
// Found a path to the destination [NotNull]
if (comparer.Equals(node, destination)) public static Dictionary<T2, IEnumerable<T>> BreadthFirstSearchManyDestinations<T, T2>(T root,
return GetPath(destination, nodeParents).Reverse(); Dictionary<T2, T> destinations,
} Func<T, IEnumerable<T>>
} getChildren)
{
if (getChildren == null)
throw new ArgumentNullException("getChildren");
return null; return BreadthFirstSearchPathManyDestinations(root, destinations, getChildren, EqualityComparer<T>.Default);
} }
[NotNull] [NotNull]
public static Dictionary<T2, IEnumerable<T>> BreadthFirstSearchPathManyDestinations<T, T2>(T root, Dictionary<T2, T> destinations, public static Dictionary<T2, IEnumerable<T>> BreadthFirstSearchPathManyDestinations<T, T2>(T root,
Func<T, IEnumerable<T>> getChildren, Dictionary<T2, T>
IEqualityComparer<T> comparer) destinations,
{ Func<T, IEnumerable<T>>
if (getChildren == null) getChildren,
throw new ArgumentNullException("getChildren"); IEqualityComparer<T>
comparer)
{
if (destinations == null)
throw new ArgumentNullException("destinations");
if (comparer == null) if (getChildren == null)
throw new ArgumentNullException("comparer"); throw new ArgumentNullException("getChildren");
Dictionary<T2, T> destinationsToBeProcessed = new Dictionary<T2, T>(destinations); if (comparer == null)
List<T> destinationsProcessed = new List<T>(); throw new ArgumentNullException("comparer");
Dictionary<T2, IEnumerable<T>> pathsToReturn = new Dictionary<T2, IEnumerable<T>>();
//Edge case, root is the destination Dictionary<T2, T> destinationsToBeProcessed = new Dictionary<T2, T>(destinations);
foreach (var destination in destinationsToBeProcessed.Where(destination => comparer.Equals(root, destination.Value))) List<T> destinationsProcessed = new List<T>();
{ Dictionary<T2, IEnumerable<T>> pathsToReturn = new Dictionary<T2, IEnumerable<T>>();
destinationsProcessed.Add(destination.Value);
pathsToReturn.Add(destination.Key, new[] { root });
}
foreach (var destination in destinationsProcessed) // Edge case, root is the destination
{ foreach (
destinationsToBeProcessed.RemoveValue(destination); KeyValuePair<T2, T> destination in
} destinationsToBeProcessed.Where(destination => comparer.Equals(root, destination.Value)))
destinationsProcessed.Clear(); {
if (destinationsToBeProcessed.Count == 0) destinationsProcessed.Add(destination.Value);
{ pathsToReturn.Add(destination.Key, new[] {root});
return pathsToReturn; }
}
Queue<T> queue = new Queue<T>(); foreach (T destination in destinationsProcessed)
queue.Enqueue(root); {
destinationsToBeProcessed.RemoveValue(destination);
}
destinationsProcessed.Clear();
if (destinationsToBeProcessed.Count == 0)
{
return pathsToReturn;
}
Dictionary<T, T> nodeParents = new Dictionary<T, T>(); Queue<T> queue = new Queue<T>();
queue.Enqueue(root);
while (queue.Count > 0) Dictionary<T, T> nodeParents = new Dictionary<T, T>();
{
T current = queue.Dequeue();
foreach (T node in getChildren(current).Where(node => !nodeParents.ContainsKey(node))) while (queue.Count > 0)
{ {
queue.Enqueue(node); T current = queue.Dequeue();
nodeParents.Add(node, current);
foreach (var destination in destinationsToBeProcessed.Where(destination => comparer.Equals(node, destination.Value))) foreach (T node in getChildren(current).Where(node => !nodeParents.ContainsKey(node)))
{ {
destinationsProcessed.Add(destination.Value); queue.Enqueue(node);
pathsToReturn.Add(destination.Key, GetPath(destination.Value, nodeParents).Reverse()); nodeParents.Add(node, current);
}
foreach (var destination in destinationsProcessed)
{
destinationsToBeProcessed.RemoveValue(destination);
}
destinationsProcessed.Clear();
if (destinationsToBeProcessed.Count == 0)
{
return pathsToReturn;
}
}
}
return pathsToReturn; foreach (
} KeyValuePair<T2, T> destination in
destinationsToBeProcessed.Where(destination => comparer.Equals(node, destination.Value)))
{
destinationsProcessed.Add(destination.Value);
pathsToReturn.Add(destination.Key, GetPath(destination.Value, nodeParents).Reverse());
}
/// <summary> foreach (T destination in destinationsProcessed)
/// Walks through a map of nodes from the starting point. destinationsToBeProcessed.RemoveValue(destination);
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="start"></param>
/// <param name="nodeParents"></param>
/// <returns></returns>
private static IEnumerable<T> GetPath<T>(T start, IDictionary<T, T> nodeParents)
{
IcdHashSet<T> visited = new IcdHashSet<T>();
while (true) destinationsProcessed.Clear();
{
yield return start;
visited.Add(start);
T next; if (destinationsToBeProcessed.Count == 0)
if (!nodeParents.TryGetValue(start, out next)) return pathsToReturn;
break; }
}
if (visited.Contains(next)) return pathsToReturn;
break; }
start = next; /// <summary>
} /// Walks through a map of nodes from the starting point.
} /// </summary>
} /// <typeparam name="T"></typeparam>
/// <param name="start"></param>
/// <param name="nodeParents"></param>
/// <returns></returns>
private static IEnumerable<T> GetPath<T>(T start, IDictionary<T, T> nodeParents)
{
IcdHashSet<T> visited = new IcdHashSet<T>();
while (true)
{
yield return start;
visited.Add(start);
T next;
if (!nodeParents.TryGetValue(start, out next))
break;
if (visited.Contains(next))
break;
start = next;
}
}
}
} }