Пример #1
0
        static void tryAddNode(CaveNode next)
        {
            if (closedNodes.Contains(next))
            {
                return;
            }
            CaveNode candidate;

            if (openNodes.Contains(next)) //update f and g as necessary
            {
                openNodes.TryGetValue(next, out candidate);
                candidate.costToNode = Math.Min(candidate.costToNode, next.costToNode);
                candidate.f          = Math.Min(candidate.f, next.f);
            }
            else
            {
                openNodes.Add(next);
            }
        }
Пример #2
0
        public static void Run()
        {
            Console.WriteLine("\nDay 22");

            int[][] erosionGrid;
            int[][] terrainGrid;
            int     targetX;
            int     targetY;
            int     depth;

            using (StreamReader reader = new StreamReader("input/input22.txt"))
            {
                depth = int.Parse(reader.ReadLine().Split(' ')[1]);
                string[] target = reader.ReadLine().Split(' ', ',');
                targetX     = int.Parse(target[1]);
                targetY     = int.Parse(target[2]);
                erosionGrid = new int[(targetY + 100)][];
                terrainGrid = new int[(targetY + 100)][];
                for (int row = 0; row < erosionGrid.Length; row++)
                {
                    erosionGrid[row] = new int[targetX + 100];
                    terrainGrid[row] = new int[targetX + 100];
                }
            }
            for (int y = 0; y < erosionGrid.Length; y++)
            {
                for (int x = 0; x < erosionGrid[y].Length; x++)
                {
                    if (targetX == x && targetY == y)
                    {
                        erosionGrid[y][x] = depth % 20183;
                    }
                    else if (x == 0)
                    {
                        if (y == 0)
                        {
                            erosionGrid[y][x] = depth % 20183;
                        }
                        else
                        {
                            erosionGrid[y][x] = (y * 48271 + depth) % 20183;
                        }
                    }
                    else if (y == 0)
                    {
                        erosionGrid[y][x] = (x * 16807 + depth) % 20183;
                    }
                    else
                    {
                        erosionGrid[y][x] = (erosionGrid[y - 1][x] * erosionGrid[y][x - 1] + depth) % 20183;
                    }
                    terrainGrid[y][x] = erosionGrid[y][x] % 3;
                }
            }
            Console.WriteLine("Total Risk Level: " + (terrainGrid.Take(targetY + 1).Sum(x => x.Take(targetX + 1).Sum())));

            openNodes.Add(new CaveNode(null, 0, 0, targetX, targetY, 0, 0)); //start with torch
            while (true)
            {
                CaveNode currNode = openNodes.FirstOrDefault();
                if (currNode.x == targetX && currNode.y == targetY)
                {
                    if (currNode.equipment == 0)
                    {
                        Console.WriteLine("Quickest Time to Target: " + currNode.costToNode);
                        break;
                    }
                    else //switch to torch and check other candidates for faster pathing that arrive with the torch already equipped
                    {
                        currNode.equipment = 0;
                        currNode.f        += 7;
                    }
                }
                else
                {
                    closedNodes.Add(currNode);
                    openNodes.Remove(currNode);

                    int terrain;
                    if (currNode.x > 0) //check if array index is in bounds, then continue with current equipment if possible, else switch to proper equipment
                    {
                        terrain = terrainGrid[currNode.y][currNode.x - 1];
                        if (currNode.equipment != (terrain + 2) % 3)
                        {
                            tryAddNode(new CaveNode(currNode, currNode.x - 1, currNode.y, targetX, targetY, terrain, currNode.equipment));
                        }
                        else
                        {
                            tryAddNode(new CaveNode(currNode, currNode.x - 1, currNode.y, targetX, targetY, terrain, (3 + terrain - currNode.terrain + currNode.equipment) % 3));
                        }
                    }
                    if (currNode.y > 0)
                    {
                        terrain = terrainGrid[currNode.y - 1][currNode.x];
                        if (currNode.equipment != (terrain + 2) % 3)
                        {
                            tryAddNode(new CaveNode(currNode, currNode.x, currNode.y - 1, targetX, targetY, terrain, currNode.equipment));
                        }
                        else
                        {
                            tryAddNode(new CaveNode(currNode, currNode.x, currNode.y - 1, targetX, targetY, terrain, (3 + terrain - currNode.terrain + currNode.equipment) % 3));
                        }
                    }
                    if (currNode.y < terrainGrid.Length - 1)
                    {
                        terrain = terrainGrid[currNode.y + 1][currNode.x];
                        if (currNode.equipment != (terrain + 2) % 3)
                        {
                            tryAddNode(new CaveNode(currNode, currNode.x, currNode.y + 1, targetX, targetY, terrain, currNode.equipment));
                        }
                        else
                        {
                            tryAddNode(new CaveNode(currNode, currNode.x, currNode.y + 1, targetX, targetY, terrain, (3 + terrain - currNode.terrain + currNode.equipment) % 3));
                        }
                    }
                    if (currNode.x < terrainGrid[currNode.y].Length - 1)
                    {
                        terrain = terrainGrid[currNode.y][currNode.x + 1];
                        if (currNode.equipment != (terrain + 2) % 3)
                        {
                            tryAddNode(new CaveNode(currNode, currNode.x + 1, currNode.y, targetX, targetY, terrain, currNode.equipment));
                        }
                        else
                        {
                            tryAddNode(new CaveNode(currNode, currNode.x + 1, currNode.y, targetX, targetY, terrain, (3 + terrain - currNode.terrain + currNode.equipment) % 3));
                        }
                    }
                }
            }
        }