Example #1
0
 public MapSearchInfo(MapSearchInfo m)
 {
     positions = new Position[m.positions.Length];
     m.positions.CopyTo(positions, 0);
     found = new SortedSet <char>(m.found);
     steps = m.steps;
 }
Example #2
0
        static string CreateStr(MapSearchInfo msi)
        {
            string ps = "";

            foreach (Position p in msi.positions)
            {
                ps += p.x.ToString() + ',' + p.y.ToString() + ',';
            }
            return(string.Join("", msi.found) + ps);
        }
Example #3
0
        static int CollectAllKeys(Map m, List <Position> positions)
        {
            Dictionary <string, MapSearchInfo> infoSteps = new Dictionary <string, MapSearchInfo>();
            MapSearchInfo msi0 = new MapSearchInfo(positions.ToArray(), new SortedSet <char>(), 0);

            infoSteps[CreateStr(msi0)] = msi0;
            int minSteps = int.MaxValue;

            while (infoSteps.Count > 0)
            {
                PrintInfoSteps(infoSteps);
                Dictionary <string, MapSearchInfo> nextInfoSteps = new Dictionary <string, MapSearchInfo>();
                foreach (var v in infoSteps)
                {
                    Dictionary <char, (int steps, int idx)> keyDists = FindDirectlyReachableKeyDistances(m, v.Value);
                    if (keyDists.Count == 0)
                    {
                        if (v.Value.steps < minSteps)
                        {
                            minSteps = v.Value.steps;
                        }
                    }
                    foreach (var kvp in keyDists)
                    {
                        MapSearchInfo nextMsi = new MapSearchInfo(v.Value);
                        nextMsi.steps += kvp.Value.steps;
                        FindInMap(m, kvp.Key, ref nextMsi.positions[kvp.Value.idx]);
                        nextMsi.found.Add(kvp.Key);
                        Position p  = new Position();
                        char     c2 = char.ToUpper(kvp.Key);
                        if (FindInMap(m, c2, ref p))
                        {
                            nextMsi.found.Add(c2);
                        }
                        string sid = CreateStr(nextMsi);
                        if (!nextInfoSteps.ContainsKey(sid) || nextInfoSteps[sid].steps > nextMsi.steps)
                        {
                            nextInfoSteps[sid] = nextMsi;
                        }
                    }
                }
                infoSteps = nextInfoSteps;
            }
            Console.WriteLine();
            return(minSteps);
        }
Example #4
0
        static Dictionary <char, (int, int)> FindDirectlyReachableKeyDistances(Map m, MapSearchInfo msi)
        {
            List <Position> toVisit = new List <Position>(msi.positions);
            Dictionary <Position, (int steps, int idx)> steps = new Dictionary <Position, (int, int)>();

            for (int i = 0; i < msi.positions.Length; i++)
            {
                steps[msi.positions[i]] = (0, i);
            }
            List <Position> keyPos = new List <Position>();

            while (toVisit.Count > 0)
            {
                List <Position> toVisitNext = new List <Position>();
                foreach (Position p in toVisit)
                {
                    foreach (Position d in directions)
                    {
                        Position nextPos = p + d;
                        char     c       = m[nextPos];
                        if (c != '#')
                        {
                            if (c == '.' || c == '@' || msi.found.Contains(c) || char.IsLower(c))
                            {
                                (int steps, int idx)s = (steps[p].steps + 1, steps[p].idx);
                                if (!steps.ContainsKey(nextPos) || s.steps < steps[nextPos].steps)
                                {
                                    steps[nextPos] = s;
                                    if (c == '.' || c == '@' || msi.found.Contains(c))
                                    {
                                        toVisitNext.Add(nextPos);
                                    }
                                    else
                                    {
                                        keyPos.Add(nextPos);
                                    }
                                }
                            }
                        }
                    }
                }
                toVisit = toVisitNext;
            }
            Dictionary <char, (int, int)> foundChars = new Dictionary <char, (int, int)>();

            foreach (Position p in keyPos)
            {
                foundChars[m[p]] = steps[p];
            }
            return(foundChars);
        }