1
0
Quellcode durchsuchen

Optimized algo, but still bad result...

bastien.monsarrat vor 6 Jahren
Ursprung
Commit
5ce1290668
1 geänderte Dateien mit 63 neuen und 64 gelöschten Zeilen
  1. 63 64
      D20.1/Program.cs

+ 63 - 64
D20.1/Program.cs

@@ -11,24 +11,40 @@ namespace D20._1
     {
         public class Group
         {
+            public int Id { get; set; }
             public int Level { get; set; }
             public string Str { get; set; }
             public List<Group> Groups { get; set; }
-            public Group() => Groups = new List<Group>();
+            public SortedSet<string> Possibilities { get; set; }
+            public Group()
+            {
+                Groups = new List<Group>();
+                Possibilities = new SortedSet<string>(new PC());
+                Str = "";
+                Id = 1;
+            }
+        }
+
+        class PC : IComparer<string>
+        {
+            public int Compare(string x, string y) => y.Length.CompareTo(x.Length);
         }
 
-        static IEnumerable<string> CombinePossibilities(string Str, List<(string, IEnumerable<string>)> prev, int depth = 0)
+        static IEnumerable<string> CombinePossibilities(string Str, List<Group> children, int depth = 0)
         {
-            if (depth == prev.Count) { yield return Str; yield break; }
+            if (depth == children.Count) { yield return Str; yield break; }
 
-            var prevStr = prev[depth];
+            var child = children[depth];
 
-            foreach (var prevPos in prevStr.Item2)
-                foreach (var t in CombinePossibilities(Str.Replace(prevStr.Item1, prevPos), prev, depth + 1))
+            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;
+                }
         }
 
-        static Group Test(int level, string priority, string regex, int index)
+        static Group BuildGroups(int level, string priority, string regex, int index)
         {
             if (index >= regex.Length) return null;
 
@@ -43,21 +59,50 @@ namespace D20._1
                 if (priority[index] > level && capture)
                 {
                     capture = false;
-                    var childGroup = Test(level + 1, priority, regex, index);
-                    if (childGroup != null) group.Groups.Add(childGroup);
+                    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)
+                {
                     capture = true;
-
-                group.Str += regex[index];
+                    group.Str += regex[index];
+                }
 
                 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);
+            }
+        }
+
         static void Main(string[] args)
         {
             if (args.Length < 1) return;
@@ -67,9 +112,11 @@ namespace D20._1
             var regex = file.ReadToEnd();
             file.Close();
 
-            //regex = @"^E(N|S(E|N)(W|S)SE)ES$";
-            //regex = @"^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$";
+            //regex = @"^ENNWSWW(NEWS|)SSSEEN(WNSE|)EE(SWEN|)NNN$";
+            regex = @"^WSSEESWWWNW(S|NENNEEEENN(ESSSSW(NWSW|SSEN)|WSWWN(E|WWS(E|SS))))$";
+            //regex = @"^N(EEENWWW|N)$";
 
+            regex = regex.TrimStart('^').TrimEnd('$');
             int par = 0, maxpar = 0;
             var priority = "";
             for (var i = 0; i < regex.Length; ++i)
@@ -83,66 +130,18 @@ namespace D20._1
                 priority += (char)par;
             }
 
-            //var tt = Test(0, priority, regex, 0);
-
-            Stack<(int, Group)> groups = new Stack<(int, Group)>();
-            groups.Push((0, new Group() { Level = 0, Str = regex }));
-
-            for (var level = 1; level <= maxpar; ++level)
-            {
-                Group cur = new Group() { Level = level, Str = "" };
-                for (var i = 1; i < regex.Length; ++i)
-                {
-                    if (priority[i] >= level) cur.Str += regex[i];
-
-                    if (priority[i] < level && priority[i - 1] >= level)
-                    {
-                        cur.Str += regex[i];
-                        groups.Push((level, cur));
-                        cur = new Group() { Level = level, Str = "" };
-                    }
-                }
-            }
-
-            var prevm1 = new List<(string, IEnumerable<string>)>();
+            var root = BuildGroups(0, priority, regex, 0);
 
             var sw = Stopwatch.StartNew();
 
-            for (var level = maxpar; level >= 0; --level)
-            {
-                HashSet<string> all = new HashSet<string>();
-                while (groups.Count > 0 && groups.Peek().Item1 == level)
-                    all.Add(groups.Pop().Item2.Str);
-
-                var prev = new List<(string, IEnumerable<string>)>(prevm1);
-
-                prevm1.Clear();
-                foreach (var a in all)
-                {
-                    var possibilities = new HashSet<string>();
-
-                    var list = prev.Where(p => a.Contains(p.Item1)).ToList();
-
-                    var res = CombinePossibilities(a, list);
-
-                    foreach (var pp in res)
-                    {
-                        var ppp = pp.TrimStart('(').TrimEnd(')').Split("|");
-                        foreach (var pppp in ppp) possibilities.Add(pppp);
-                    }
-
-                    prevm1.Add((a, possibilities));
-                }
-            }
+            Test(root);
 
             sw.Stop();
 
             Console.WriteLine(sw.ElapsedMilliseconds);
 
-            List<int> result = new List<int>();
-            
             int max = 0;
-            foreach (var path in prevm1.First().Item2)
+            foreach (var path in root.Possibilities)
             {
                 var r = GetResult(path);
                 if (r > max) max = r;