Преглед изворни кода

Day 21 part 2 - took me a while to find the mistake with the overall odds and evens

Lukas Angerer пре 2 година
родитељ
комит
8f7b1e2586
2 измењених фајлова са 81 додато и 5 уклоњено
  1. 75 4
      Day21/Map.cs
  2. 6 1
      Day21/Program.cs

+ 75 - 4
Day21/Map.cs

@@ -52,10 +52,11 @@ public class Map
         Console.WriteLine();
     }
 
-    public long ReachableTiles(int steps)
+    public long ReachableTiles(long steps, Vec? start = null, bool print = false)
     {
+        start ??= _start!.Position;
         var reachable = new HashSet<Vec>();
-        reachable.Add(_start!.Position);
+        reachable.Add(start.Value);
         
         for (int i = 0; i < steps; i++)
         {
@@ -70,12 +71,69 @@ public class Map
 
             reachable = next;
         }
-        
-        Print(reachable);
+
+        if (print)
+        {
+            Print(reachable);
+        }
 
         return reachable.Count;
     }
 
+    public long ReachableLarge(long steps)
+    {
+        var fullMap = PassableTileCount();
+        Console.WriteLine($"Width: {_width} | Height: {_height}");
+        Console.WriteLine($"Odd Reachable: {fullMap.Odd} | Even Reachable: {fullMap.Even}");
+        var even = steps % 2 == 0;
+        Console.WriteLine($"Step count is even: {even}");
+        
+        var count = 0L;
+
+        var fullChunks = ((steps - (_width / 2)) / _width) - 1;
+        Console.WriteLine($"Full chunks after center: {fullChunks}");
+        
+        // round UP to the nearest multiple of 2
+        count += Square(fullChunks / 2 * 2 + 1) * fullMap.Odd;
+        // round DOWN to the nearest multiple of 2
+        count += Square((fullChunks + 1) / 2 * 2) * fullMap.Even;
+
+        var majorSteps = (long)(_width + _width / 2 - 1);
+        var minorSteps = (long)(_width / 2 - 1);
+
+
+        var cornerT = ReachableTiles(_height - 1, new Vec(_width / 2, _height - 1));
+        count += cornerT;
+        var cornerB = ReachableTiles(_height - 1, new Vec(_width / 2, 0));
+        count += cornerB;
+        var cornerR = ReachableTiles(_width - 1, new Vec(_width - 1, _height / 2));
+        count += cornerR;
+        var cornerL = ReachableTiles(_width - 1, new Vec(0, _height / 2));
+        count += cornerL;
+        Console.WriteLine($"Corners: {cornerT} {cornerR} {cornerB} {cornerL}");
+        var largeBL = ReachableTiles(majorSteps, new Vec(0, _height - 1));
+        count += fullChunks * largeBL;
+        var smallBL = ReachableTiles(minorSteps, new Vec(0, _height - 1));
+        count += (fullChunks + 1) * smallBL;
+        var largeTL = ReachableTiles(majorSteps, new Vec(0, 0));
+        count += fullChunks * largeTL;
+        var smallTL = ReachableTiles(minorSteps, new Vec(0, 0));
+        count += (fullChunks + 1) * smallTL;
+        var largeTR = ReachableTiles(majorSteps, new Vec(_width - 1, 0));
+        count += fullChunks * largeTR;
+        var smallTR = ReachableTiles(minorSteps, new Vec(_width - 1, 0));
+        count += (fullChunks + 1) * smallTR;
+        var largeBR = ReachableTiles(majorSteps, new Vec(_width - 1, _height - 1));
+        count += fullChunks * largeBR;
+        var smallBR = ReachableTiles(minorSteps, new Vec(_width - 1, _height - 1));
+        count += (fullChunks + 1) * smallBR;
+
+        Console.WriteLine($"Small Diagonals: {smallTL} {smallTR} {smallBL} {smallBR}");
+        Console.WriteLine($"Large Diagonals: {largeTL} {largeTR} {largeBL} {largeBR}");
+
+        return count;
+    }
+
     private IEnumerable<Vec> Surrounding(Vec middle)
     {
         yield return middle.Add(ScreenSpace.Up);
@@ -93,4 +151,17 @@ public class Map
 
         return _map[p.X, p.Y];
     }
+
+    private long Square(long num)
+    {
+        return num * num;
+    }
+    
+    private (long Even, long Odd) PassableTileCount()
+    {
+        // Note: there is ONE single unreachable tile that is not a rock, but surrounded by rocks, so we have to
+        // "fill" to find the correct numbers
+
+        return (ReachableTiles(_width + 1), ReachableTiles(_width));
+    }
 }

+ 6 - 1
Day21/Program.cs

@@ -18,7 +18,12 @@ var inputFile = args[0];
 var parser = new Parser();
 var map = parser.Parse(inputFile);
 
-var reachable = map.ReachableTiles(64);
+var reachable = map.ReachableTiles(64, print: true);
+Console.WriteLine();
+Console.WriteLine($"Reachable: {reachable}");
+Console.WriteLine();
+
+reachable = map.ReachableLarge(26501365);
 Console.WriteLine();
 Console.WriteLine($"Reachable: {reachable}");