Quellcode durchsuchen

Day 12 part 1 using recursion 'parsing'

Lukas Angerer vor 2 Jahren
Ursprung
Commit
5245f76c14
4 geänderte Dateien mit 75 neuen und 57 gelöschten Zeilen
  1. 0 42
      Day12/Arrangement.cs
  2. 0 6
      Day12/Checksum.cs
  3. 8 1
      Day12/Program.cs
  4. 67 8
      Day12/WellRecord.cs

+ 0 - 42
Day12/Arrangement.cs

@@ -1,42 +0,0 @@
-namespace Day12;
-
-public class Arrangement
-{
-    private readonly IList<byte> _items;
-    
-    public Arrangement(string arrangement)
-    {
-        _items = arrangement.Select(c =>
-        {
-            switch (c)
-            {
-                case '.':
-                    return (byte) 0;
-                case '#':
-                    return (byte) 1;
-                default:
-                    return (byte) 255;
-            }
-        }).ToList();
-    }
-
-    public Checksum CalculateChecksum()
-    {
-        var values = new List<int>();
-        var c = 0;
-        foreach (var i in _items)
-        {
-            if (i == 1)
-            {
-                c++;
-            }
-            else if (c > 0)
-            {
-                values.Add(c);
-                c = 0;
-            }
-        }
-
-        return new Checksum(values.ToArray());
-    }
-}

+ 0 - 6
Day12/Checksum.cs

@@ -1,6 +0,0 @@
-namespace Day12;
-
-public record Checksum(int[] Values)
-{
-    
-}

+ 8 - 1
Day12/Program.cs

@@ -17,10 +17,17 @@ if (args.Length < 1)
 var inputFile = args[0];
 var parser = new Parser();
 var records = parser.Parse(inputFile);
+var sum = 0L;
 
 foreach (var r in records)
 {
-    Console.WriteLine($"{string.Join(", ", r.Checksum.Values)}");
+    r.Print();
+    var count = r.Count();
+    Console.WriteLine($"Count: {count}");
+    sum += count;
 }
 
+Console.WriteLine();
+Console.WriteLine($"Sum Total: {sum}");
+
 return 0;

+ 67 - 8
Day12/WellRecord.cs

@@ -4,17 +4,76 @@ namespace Day12;
 
 public class WellRecord
 {
-    public Arrangement Pattern { get; }
-    public Checksum Checksum { get; }
+    private readonly string _record;
+    private readonly int[] _checksum;
+    
+    private static readonly Dictionary<string, long> MemoMap = new Dictionary<string, long>();
 
     public WellRecord(string record, int[] checksum)
     {
-        Pattern = new Arrangement(record);
-        Checksum = new Checksum(checksum);
+        _record = record;
+        _checksum = checksum;
     }
 
-    // public IEnumerable<List<int>> GeneratePermuations(int n, int choose)
-    // {
-    //     
-    // }
+    public void Print()
+    {
+        Console.WriteLine($"{_record} => {string.Join(", ", _checksum)}");
+    }
+
+    public long Count()
+    {
+        return CountPermuations(_record, _checksum);
+    }
+
+    private long CountPermuations(string tail, int[] values)
+    {
+        var key = Key(tail, values);
+        if (MemoMap.TryGetValue(key, out long count))
+        {
+            Console.WriteLine($"Memoized {key}: {count}");
+            return count;
+        }
+
+        if (tail == String.Empty)
+        {
+            // when the tail is empty and we have no runs left then that is valid, otherwise invalid
+            return values.Length == 0 ? 1 : 0;
+        }
+
+        if (values.Length == 0)
+        {
+            // no remaining runs to count - if there are still # left in the tail then that is invalid, otherwise valid
+            return tail.Contains('#') ? 0 : 1;
+        }
+        
+        var dotCount = 0L;
+        var hashCount = 0L;
+        if (tail[0] is '.' or '?')
+        {
+            dotCount = CountPermuations(tail[1..], values);
+        }
+
+        if (tail[0] is '#' or '?' && tail.Length >= values[0])
+        {
+            var hasRunOfN = !tail[..values[0]].Contains('.');
+            if (tail.Length > values[0] && hasRunOfN && tail[values[0]] != '#')
+            {
+                hashCount = CountPermuations(tail[(values[0] + 1)..], values.Skip(1).ToArray());
+            }
+            else if (tail.Length == values[0] && hasRunOfN)
+            {
+                hashCount = CountPermuations(tail[values[0]..], values.Skip(1).ToArray());
+            }
+        }
+
+        var result = dotCount + hashCount;
+        Console.WriteLine($"Computed {key}: {result}");
+        MemoMap[key] = result;
+        return result;
+    }
+
+    private static string Key(string tail, int[] values)
+    {
+        return tail + string.Join(",", values);
+    }
 }