コード例 #1
0
ファイル: Day20.cs プロジェクト: ntellos13/AdventOfCode
        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);
        }
コード例 #2
0
ファイル: Day16.cs プロジェクト: ntellos13/AdventOfCode
        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);
            }
        }
コード例 #3
0
ファイル: Day18.cs プロジェクト: ntellos13/AdventOfCode
        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);
        }