public void ReturnsEmptySetIfNothingFound() { var bfs = new BreadthFirstSearch <int>(EqualityComparer <int> .Default, _ => Enumerable.Empty <int>()); var result = bfs.FindAll(0, x => x < 0); Assert.AreEqual(0, result.Count); }
public void ParallelSearchIsExhaustive() { var expansionCount = 0; IEnumerable <Point> Expander(Point p) { _ = Interlocked.Increment(ref expansionCount); if (p.X + p.Y >= 100) { yield break; } yield return(p + new Size(1, 0)); yield return(p + new Size(0, 1)); } var bfs = new BreadthFirstSearch <Point>(EqualityComparer <Point> .Default, Expander) { PerformParallelSearch = true }; var result = bfs.FindAll(Point.Empty, p => (p.X + p.Y) % 5 == 0); var resultCount = (100 / 5 * (100 + 5) / 2) + (100 / 5) + 1; Assert.AreEqual(resultCount, result.Count); Assert.AreEqual(5151, expansionCount); }
public void FindsInitialNode() { var bfs = new BreadthFirstSearch <int>(EqualityComparer <int> .Default, _ => Enumerable.Empty <int>()); var result = bfs.FindAll(33, x => x > 0); Assert.AreEqual(1, result.Count); Assert.AreEqual(0, result[0].Length); Assert.AreEqual(1, result[0].Steps.Length); Assert.AreEqual(33, result[0].Steps[0]); }
static void Main(string[] args) { var input = File.ReadAllLines("../../../input.txt"); var sw = new Stopwatch(); sw.Start(); var wires = input.Select(WireToPoints).ToList(); var crossings = new HashSet <Point>(wires[0].Keys.Intersect(wires[1].Keys)); var closest = crossings.MinBy(DistanceFromOrigin).First(); Console.WriteLine($"Part 1: point {closest} is in both wires and close to the origin."); var shortest = crossings.MinBy(x => wires[0][x] + wires[1][x]).First(); var delay = wires[0][shortest] + wires[1][shortest]; Console.WriteLine($"Part 2: point {shortest} has signal delay {delay}"); var search1 = new BreadthFirstSearch <Point>(EqualityComparer <Point> .Default, p => _mapDirectionToSize.Values.Select(s => p + s).Where(wires[0].Keys.Contains) ) { PerformParallelSearch = false }; var wire1 = search1.FindAll(Point.Empty, p => crossings.Contains(p)) .ToDictionary(x => x.Target, x => x.Length); var search2 = new BreadthFirstSearch <Point>(EqualityComparer <Point> .Default, p => _mapDirectionToSize.Values.Select(s => p + s).Where(wires[1].Keys.Contains) ) { PerformParallelSearch = false }; var wire2 = search2.FindAll(Point.Empty, p => crossings.Contains(p)) .ToDictionary(x => x.Target, x => x.Length); var shortedCrossings = crossings.MinBy(x => wire1[x] + wire2[x]).First(); delay = wire1[shortedCrossings] + wire2[shortedCrossings]; Console.WriteLine($"Part 3: point {shortedCrossings} has signal delay {delay}"); sw.Stop(); Console.WriteLine($"Solving took {sw.ElapsedMilliseconds}ms."); _ = Console.ReadLine(); }
public void FindTargetSetInInfiniteGraph() { var bfs = new BreadthFirstSearch <int>(EqualityComparer <int> .Default, x => new[] { x * 2, x * 3 }); var result = bfs.FindAll(1, x => x < 30, null, 12); var expected = new[] { 1, 2, 4, 8, 16, 3, 6, 12, 24, 9, 18, 27 }; Assert.AreEqual(12, result.Count); foreach (var target in expected) { Assert.IsTrue(result.Any(p => p.Target == target)); } }
public void FindAllTargetsInFiniteGraph() { var bfs = new BreadthFirstSearch <int>( EqualityComparer <int> .Default, (int x) => (x > 100) ? Enumerable.Empty <int>() : new[] { x * 2, x * 3 }); var result = bfs.FindAll(1, x => x < 30); var expected = new[] { 1, 2, 4, 8, 16, 3, 6, 12, 24, 9, 18, 27 }; Assert.AreEqual(12, result.Count); foreach (var target in expected) { Assert.IsTrue(result.Any(p => p.Target == target)); } }
static void Main() { var input = File.ReadAllLines("../../../input.txt"); var sw = new Stopwatch(); sw.Start(); //var items = input.Select(s => s.Split(')')); //var orbitedby = items.ToLookup(x => x[0], x => x[1]); //var orbits = items.ToDictionary(x => x[1], x => x[0]); //var search = new BreadthFirstSearch<string>( // EqualityComparer<string>.Default, // node => orbitedby[node].Concat(orbits.GetOrEmpty(node))) //{ PerformParallelSearch = false }; //var depths = search.FindAll("COM", x => true); //var sum = depths.Sum(path => path.Length); //Console.WriteLine($"Part 1: The total number of orbits is {sum}."); //var path = search.FindFirst("SAN", x => x == "YOU"); //Console.WriteLine($"Part 2: The route von Santa to you has {path.Length - 2} transfers."); var graph = Graph.FromEdges(input, s => s.Split(')').ToTuple2()); var search = new BreadthFirstSearch <GraphNode <string, string> >( graph.NodeComparer, node => node.Neighbors) { PerformParallelSearch = false }; var depths = search.FindAll(graph.Nodes["COM"], x => true); var sum = depths.Sum(path => path.Length); Console.WriteLine($"Part 1: The total number of orbits is {sum}."); var path = search.FindFirst(graph.Nodes["SAN"], x => x.Value == "YOU"); Console.WriteLine($"Part 2: The route von Santa to you has {path.Length - 2} transfers."); sw.Stop(); Console.WriteLine($"Solving took {sw.ElapsedMilliseconds}ms."); _ = Console.ReadLine(); }
private static void Main(string[] args) { var inputText = File.ReadAllLines(@"../../../input.txt"); field = inputText.Select(x => x.ToCharArray()).ToArray(); rows = field.Length; columns = field[0].Length; var allNumbers = field.SelectMany(x => x).Where(char.IsDigit).ToArray(); var numberPositions = new Dictionary <char, Coordinate>(); for (var rowIndex = 0; rowIndex < rows; rowIndex++) { for (var colIndex = 0; colIndex < columns; colIndex++) { var c = new Coordinate(colIndex, rowIndex); var content = ContentAt(c); if (char.IsDigit(content)) { numberPositions.Add(content, c); } } } foreach (var position in numberPositions) { Console.WriteLine($"Number {position.Key} found at {position.Value}"); } var bfs = new BreadthFirstSearch <Coordinate, MoveDirection>(new CoordinateIdentical(), GetPossibleMovements, GetPosition); var distances = new Dictionary <string, int>(); foreach (var number in numberPositions.Keys) { var others = bfs.FindAll(numberPositions[number], coords => ContentAt(coords) > number); foreach (var other in others) { var edge1 = string.Concat(number, ContentAt(other.Target)); var edge2 = string.Concat(ContentAt(other.Target), number); var edgeLength = other.Length - 1; distances.Add(edge1, edgeLength); distances.Add(edge2, edgeLength); Console.WriteLine($"Edge {edge1} / {edge2} is {edgeLength} long."); } } var allTrips = new Permutations <char>(allNumbers); var allTripsWithLengths = new Dictionary <string, int>(); foreach (IList <char> trip in allTrips) { if (trip[0] != '0') { continue; } trip.Add('0'); var name = string.Concat(trip); var length = 0; foreach (var walk in trip.PairwiseWithOverlap()) { var edge = string.Concat(walk.Item1, walk.Item2); length += distances[edge]; } allTripsWithLengths.Add(name, length); } Console.WriteLine(); var min = allTripsWithLengths.OrderBy(x => x.Value).Take(3); foreach (var trip in min) { Console.WriteLine($"Trip {trip.Key} is {trip.Value} long"); } Console.ReadLine(); }