1
0
Эх сурвалжийг харах

D20.2 OK with stack implementation

bastien.monsarrat 6 жил өмнө
parent
commit
448c80076c
1 өөрчлөгдсөн 34 нэмэгдсэн , 131 устгасан
  1. 34 131
      D20.1/Program.cs

+ 34 - 131
D20.1/Program.cs

@@ -9,98 +9,49 @@ namespace D20._1
 {
     class Program
     {
-        public class Group
+        static (int x, int y) MoveTo(char c, (int x, int y) pos)
         {
-            public int Id { get; set; }
-            public int Level { get; set; }
-            public string Str { get; set; }
-            public List<Group> Groups { get; set; }
-            public SortedSet<string> Possibilities { get; set; }
-            public Group()
+            switch (c)
             {
-                Groups = new List<Group>();
-                Possibilities = new SortedSet<string>(new PC());
-                Str = "";
-                Id = 1;
+                case 'N': pos.y -= 1; break;
+                case 'S': pos.y += 1; break;
+                case 'W': pos.x -= 1; break;
+                case 'E': pos.x += 1; break;
             }
-        }
 
-        class PC : IComparer<string>
-        {
-            public int Compare(string x, string y) => y.Length.CompareTo(x.Length);
+            return pos;
         }
 
-        static IEnumerable<string> CombinePossibilities(string Str, List<Group> children, int depth = 0)
+        static Dictionary<(int x, int y), int> makeMap(string input)
         {
-            if (depth == children.Count) { yield return Str; yield break; }
-
-            var child = children[depth];
-
-            foreach (var prevchildPossibility in child.Possibilities)
-                foreach (var t in CombinePossibilities(Str.Replace(("(" + (char)child.Id + ")").ToString(), prevchildPossibility), children, depth + 1))
-                {
-                    if (Str.Contains(((char)child.Id).ToString()) == false) throw new Exception();
-                    yield return t;
-                }
-        }
+            var result = new Dictionary<(int x, int y), int>();
+            var nodes = new Stack<((int x, int y), int dist)>();
+            ((int x, int y) pos, int dist) cur = ((0, 0), 0);
 
-        static Group BuildGroups(int level, string priority, string regex, int index)
-        {
-            if (index >= regex.Length) return null;
-
-            var group = new Group() { Level = level, Str = "" };
-
-            bool capture = true;
-
-            while (
-                index < regex.Length &&
-                priority[index] >= level)
+            foreach (var c in input)
             {
-                if (priority[index] > level && capture)
-                {
-                    capture = false;
-                    var childGroup = BuildGroups(level + 1, priority, regex, index);
-                    if (childGroup != null)
-                    {
-                        childGroup.Id = group.Groups.Count + 1;
-
-                        group.Str += "(" + (char)childGroup.Id;
-                        group.Groups.Add(childGroup);
-
-                    }
-                }
-                else if (priority[index] == level)
+                switch (c)
                 {
-                    capture = true;
-                    group.Str += regex[index];
+                    case 'N':
+                    case 'S':
+                    case 'E':
+                    case 'W':
+                        cur.pos = MoveTo(c, cur.pos);
+                        cur.dist++;
+                        result.TryAdd(cur.pos, cur.dist);
+                        break;
+                    case '(':
+                        nodes.Push(cur);
+                        break;
+                    case '|':
+                        cur = nodes.Peek();
+                        break;
+                    case ')':
+                        cur = nodes.Pop();
+                        break;
                 }
-
-                index++;
-            }
-
-            if (index < regex.Length) group.Str += regex[index];
-
-            return group;
-        }
-
-        static void Test(Group root)
-        {
-            IEnumerable<string> possibilities;
-            if (root.Groups.Count == 0)
-            {
-                var splittedPossibilities = root.Str.TrimStart('(').TrimEnd(')').Split("|");
-                foreach (var splittedPossibility in splittedPossibilities) root.Possibilities.Add(splittedPossibility);
-                return;
-            }
-
-            foreach (var group in root.Groups) Test(group);
-
-            possibilities = CombinePossibilities(root.Str, root.Groups);
-            foreach (var possibility in possibilities)
-            {
-                var splittedPossibilities = possibility.TrimStart('(').TrimEnd(')').Split("|");
-                foreach (var splittedPossibility in splittedPossibilities) root.Possibilities.Add(splittedPossibility);
             }
+            return result;
         }
 
         static void Main(string[] args)
@@ -117,60 +68,12 @@ namespace D20._1
             //regex = @"^N(EEENWWW|N)$";
 
             regex = regex.TrimStart('^').TrimEnd('$');
-            int par = 0, maxpar = 0;
-            var priority = "";
-            for (var i = 0; i < regex.Length; ++i)
-            {
-                if (regex[i] == '(')
-                {
-                    par++;
-                    if (par > maxpar) maxpar = par;
-                }
-                if (regex[i] == ')') par--;
-                priority += (char)par;
-            }
 
-            var root = BuildGroups(0, priority, regex, 0);
+            var map = makeMap(regex);
 
-            var sw = Stopwatch.StartNew();
-
-            Test(root);
-
-            sw.Stop();
-
-            Console.WriteLine(sw.ElapsedMilliseconds);
-
-            Dictionary<(int x, int y), int> positions = new Dictionary<(int x, int y), int>();
-            positions.Add((0, 0), 0);
-
-            foreach (var path in root.Possibilities)
-            {
-                TestResult(path, positions);
-            }
-
-            int max = positions.Max(p => p.Value);
-            int d = positions.Count(p => p.Value >= 1000);
+            int max = map.Max(p => p.Value);
+            int d = map.Count(p => p.Value >= 1000);
             Console.WriteLine($"Ex 1 : {max}\nEx 2 ; {d}");
         }
-
-        private static void TestResult(string str, Dictionary<(int x, int y), int> positions)
-        {
-            int dist = 0;
-            (int x, int y) pos = (0, 0);
-
-            foreach (var c in str)
-            {
-                switch (c)
-                {
-                    case 'N': pos.y -= 1; break;
-                    case 'S': pos.y += 1; break;
-                    case 'W': pos.x -= 1; break;
-                    case 'E': pos.x += 1; break;
-                }
-
-                if (positions.TryAdd(pos, dist + 1)) dist = dist + 1;
-                else dist = Math.Min(dist + 1, positions[pos]);
-            }
-        }
     }
 }