private void LoadMaze(string input) { GetNodes(input); BaseNodeConnection.PrintConnections(connections, 0); Console.SetCursorPosition(0, maxHeight); shortcuts = new List <NodeConnection>(); List <Node> unused = new List <Node>(); foreach (NodeConnection con in connections.Where(x => x.NodeA.CharRepresentation != '\0' && x.NodeB.CharRepresentation != '\0')) { Console.Write("" + con.NodeA.CharRepresentation + con.NodeB.CharRepresentation + " -> "); if (connections.Where(x => x.HasConnectionTo(con.NodeA)).Count() == 1) { unused.Add(con.NodeA); if (con.NodeA.X < con.NodeB.X || con.NodeA.Y < con.NodeB.Y) { con.NodeB.PortalCode = con.NodeA.PortalCode + con.NodeB.PortalCode; if (con.NodeA.X < con.NodeB.X) { con.NodeB.X++; } else { con.NodeB.Y++; } } else { con.NodeB.PortalCode += con.NodeA.PortalCode; if (con.NodeA.X > con.NodeB.X) { con.NodeB.X--; } else { con.NodeB.Y--; } } portals.Add(con.NodeB); connections.Single(x => x.HasConnectionTo(con.NodeB) && !ReferenceEquals(con, x)).RefreshDistance(); Console.WriteLine(con.NodeB.PortalCode); } else { unused.Add(con.NodeB); if (con.NodeA.X < con.NodeB.X || con.NodeA.Y < con.NodeB.Y) { con.NodeA.PortalCode += con.NodeB.PortalCode; if (con.NodeA.X < con.NodeB.X) { con.NodeA.X--; } else { con.NodeA.Y--; } } else { con.NodeA.PortalCode = con.NodeB.PortalCode + con.NodeA.PortalCode; if (con.NodeA.X > con.NodeB.X) { con.NodeA.X++; } else { con.NodeA.Y++; } } portals.Add(con.NodeA); connections.Single(x => x.HasConnectionTo(con.NodeA) && !ReferenceEquals(con, x)).RefreshDistance(); Console.WriteLine(con.NodeA.PortalCode); } } foreach (Node node in unused) { connections = connections.Where(x => !x.HasConnectionTo(node)).ToList(); nodes.Remove(node); } Console.WriteLine("================"); foreach (Node node in nodes.Where(x => !string.IsNullOrWhiteSpace(x.PortalCode))) { Console.Write(node.PortalCode + " "); var partner = nodes.FirstOrDefault(x => x.PortalCode == node.PortalCode && !ReferenceEquals(x, node)); if (partner != null && shortcuts.FirstOrDefault(x => x.HasConnectionTo(partner)) == null) { var con = new NodeConnection(node, partner, 1); shortcuts.Add(con); Console.Write(" @ing: " + con.ToString()); } else { Console.Write(" Already Connected"); } Console.WriteLine(); } start = nodes.Single(x => x.PortalCode == "AA"); end = nodes.Single(x => x.PortalCode == "ZZ"); portalAccess = new Dictionary <BaseNodeConnection, Tuple <List <Node>, double> >(); pathfind = new AStar(connections); foreach (Node portalA in portals) { foreach (Node opposite in nodes) { opposite.UpdateTargetDistance(portalA); } foreach (Node portalB in portals.Where(x => x != portalA)) { Console.CursorLeft = 0; Console.Write(assis.GetNextProgressChar()); var con = new BaseNodeConnection(portalA, portalB); if (portalAccess.Keys.SingleOrDefault(x => x.IsSameConnection(con)) != null) { continue; } var path = pathfind.GetPath(portalA, portalB, out double currCost).Select(x => (Node)x).ToList(); if (path.Last() == portalA) { path = null; } portalAccess.Add(con, new Tuple <List <Node>, double>(path, currCost)); } } //foreach (var empty in portalAccess.Where(x => x.Value.Item1 == null).ToList()) // portalAccess.Remove(empty.Key); }
public override string Solve(string input, bool part2) { //The input contains criterias, my ticket and other tickets, split and get criterias List <string> inputGroups = GetGroupedLines(input); criterias = GetCriteria(inputGroups[0]); //Split for each ticket and skip headline int invalidSum = 0; List <string> tickets = GetLines(inputGroups[2]); tickets.RemoveAt(0); int[] myTicket = GetLines(inputGroups[1])[1]. Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries). Select(x => int.Parse(x)).ToArray(); //initialize a list keeping track of all possible names for each position foreach (var field in myTicket) { possibleNames.Add(criterias.Keys.ToList()); } //Analyze the tickets ConsoleAssist assis = new ConsoleAssist(); foreach (string ticket in tickets) { Console.CursorLeft = 0; Console.Write(assis.GetNextProgressChar()); invalidSum += ValidateTicket(ticket); } Console.WriteLine(); //Order the fields by ambiguity (unambiguous -> most ambiguous) var orderedFields = possibleNames.OrderBy(x => x.Count).ToList(); for (int i = 0; i < possibleNames.Count; i++) {//get the next unambiguous field(first after all already done) var current = orderedFields.First(x => orderedFields.IndexOf(x) >= i && x.Count == 1); //Remove it's name from all other field lists foreach (var nameList in possibleNames) { if (nameList == current) { continue; } nameList.Remove(current[0]); } } //print my ticket with the right names and multiply all values starting with departure. long product = 1; for (int i = 0; i < myTicket.Length; i++) { if (possibleNames[i].Count > 1) { return("Ambiguous field name detected!"); } Console.WriteLine(possibleNames[i][0] + ": " + myTicket[i]); if (possibleNames[i][0].StartsWith("departure", StringComparison.InvariantCultureIgnoreCase)) { product *= myTicket[i]; } } if (part2) { return("Ticket Product:" + product); } else { return("Invalid Tickets: " + invalidSum); } }
private List <Node> Prioritize() { AStar pathfind = new AStar(connections); List <List <Node> > unlockedPaths = new List <List <Node> >(); List <Node> pois = keys.Concat(doors).ToList(); Console.WriteLine("Creating Tree..."); Console.WriteLine("Step 1/5 Preparing".PadRight(20)); for (int i = 0; i < connections.Count(); i++) { ((NodeConnection)connections[i]).AllowPassLockedDoor = true; Console.CursorLeft = 0; Console.Write((outAssis.GetNextProgressChar() + " " + (connections.Count / 100f * i) + "%").PadRight(20)); } Console.CursorLeft = 0; Console.WriteLine("Step 2/5 Getting Paths".PadRight(20)); for (int i = 0; i < pois.Count(); i++) { unlockedPaths.Add(pathfind.GetPath(startNode, pois[i], out List <BaseNodeConnection> cons, out double cost).Select(x => (Node)x).ToList()); Console.CursorLeft = 0; Console.Write((outAssis.GetNextProgressChar() + " " + (pois.Count / 100f * i) + "%").PadRight(20)); } Console.CursorLeft = 0; Console.WriteLine("Step 3/5 Detecting".PadRight(20)); for (int i = 0; i < unlockedPaths.Count(); i++) { List <Node> path = unlockedPaths[i]; Node target = path.Last(); Node blocker = path.LastOrDefault(x => x != target && !(x.Key == '\0' && x.Lock == '\0')); target.BlockedBy = blocker; Console.CursorLeft = 0; Console.Write((outAssis.GetNextProgressChar() + " " + (unlockedPaths.Count / 100f * i) + "%").PadRight(20)); } Console.CursorLeft = 0; Console.WriteLine("Step 4/5 Ordering".PadRight(20)); List <Node> orderedPoi = pois.Where(x => x.BlockedBy == null).ToList(); for (int i = 0; i < orderedPoi.Count(); i++) { orderedPoi.InsertRange(i + 1, pois.Where(x => x.BlockedBy == orderedPoi[i])); Console.CursorLeft = 0; Console.Write((outAssis.GetNextProgressChar() + " " + (pois.Count / 100f * i) + "%").PadRight(20)); } Console.CursorLeft = 0; Console.WriteLine("Step 5/5 Cleaning up".PadRight(20)); for (int i = 0; i < connections.Count(); i++) { ((NodeConnection)connections[i]).AllowPassLockedDoor = false; Console.CursorLeft = 0; Console.Write((outAssis.GetNextProgressChar() + " " + (connections.Count / 100f * i) + "%").PadRight(20)); } Console.CursorLeft = 0; Console.WriteLine("DONE!".PadRight(20)); return(orderedPoi); }