コード例 #1
0
        private List <JourneyStep> GetNextOptions(JourneyStep current, int caveDepth, int targetX, int targetY, HashSet <string> stepsCovered)
        {
            List <JourneyStep> options = new List <JourneyStep>();

            int[] xMods = new[] { 0, 1, 0, -1 };
            int[] yMods = new[] { -1, 0, 1, 0 };

            for (int i = 0; i < 4; i++)
            {
                int x = current.X + xMods[i];
                int y = current.Y + yMods[i];

                if (x >= 0 && y >= 0)
                {
                    int        targetErosionLevel = CalculateErosionLevel(x, y, targetX, targetY, caveDepth);
                    string     targetSoilType     = DetermineType(targetErosionLevel);
                    List <int> targetEquipment    = EquipmentAllowed(targetSoilType);
                    if (targetEquipment.Contains(current.Equipment) && stepsCovered.Add($"{x},{y},{current.Equipment}"))
                    {
                        JourneyStep newStep = new JourneyStep()
                        {
                            X           = x,
                            Y           = y,
                            Time        = current.Time + 1,
                            Switching   = 0,
                            Equipment   = current.Equipment,
                            CurrentType = targetSoilType
                        };

                        options.Add(newStep);
                    }
                }

                // Add other allowed tool option
                foreach (int otherTool in EquipmentAllowed(current.CurrentType))
                {
                    if (otherTool != current.Equipment)
                    {
                        JourneyStep newStep = new JourneyStep()
                        {
                            X           = current.X,
                            Y           = current.Y,
                            Time        = current.Time + 1,
                            Switching   = 6,
                            Equipment   = otherTool,
                            CurrentType = current.CurrentType
                        };

                        options.Add(newStep);
                    }
                }
            }

            return(options);
        }
コード例 #2
0
        public int FindBestTimeThroughCave(int caveDepth, int targetX, int targetY)
        {
            int bestTime = int.MaxValue;
            // I struggled with this one because I wanted to use constructed strings instead of custom classes for the Hashset
            // but then I did not separate the values in the strings with commas, so it was mismatching the values that overlapped
            // This made me lose hours of work.
            HashSet <string> stepsCovered = new HashSet <string>();

            Queue <JourneyStep> queue = new Queue <JourneyStep>();
            JourneyStep         start = new JourneyStep()
            {
                X           = 0,
                Y           = 0,
                Time        = 0,
                Equipment   = 2,
                CurrentType = ".",
                Switching   = 0
            };

            queue.Enqueue(start);
            stepsCovered.Add("0,0,2");

            do
            {
                JourneyStep currentStep = queue.Dequeue();

                // Handle switching
                if (currentStep.Switching > 0)
                {
                    if (currentStep.Switching != 1 ||
                        stepsCovered.Add($"{currentStep.X},{currentStep.Y},{currentStep.Equipment}"))
                    {
                        JourneyStep newStep = new JourneyStep()
                        {
                            X           = currentStep.X,
                            Y           = currentStep.Y,
                            Time        = currentStep.Time + 1,
                            Switching   = currentStep.Switching - 1,
                            Equipment   = currentStep.Equipment,
                            CurrentType = currentStep.CurrentType
                        };
                        queue.Enqueue(newStep);
                    }
                    continue;
                }

                // If the currentStep time is > best time, then discard
                if (currentStep.Time > bestTime)
                {
                    continue;
                }

                // We have reached the target
                if (currentStep.X == targetX && currentStep.Y == targetY)
                {
                    int modTime = currentStep.Equipment == 2 ? currentStep.Time : currentStep.Time + 7;
                    if (modTime < bestTime)
                    {
                        bestTime = modTime;
                    }

                    break;
                }
                // Add next options
                List <JourneyStep> options = GetNextOptions(currentStep, caveDepth, targetX, targetY, stepsCovered);
                foreach (JourneyStep option in options)
                {
                    queue.Enqueue(option);
                }
            } while (queue.Count > 0);

            return(bestTime);
        }