Răsfoiți Sursa

Day 16 part 2

Lukas Angerer 2 ani în urmă
părinte
comite
50ff533909
4 a modificat fișierele cu 96 adăugiri și 14 ștergeri
  1. 5 0
      Day16/IRay.cs
  2. 80 11
      Day16/Panel.cs
  3. 4 2
      Day16/Program.cs
  4. 7 1
      Day16/Tile.cs

+ 5 - 0
Day16/IRay.cs

@@ -47,5 +47,10 @@ public static class Rays
             var index = _rays.IndexOf(this);
             return _rays[(index + _rays.Count - 1) % _rays.Count];
         }
+
+        public override string ToString()
+        {
+            return $"{_dX}/{_dY}";
+        }
     }
 }

+ 80 - 11
Day16/Panel.cs

@@ -5,6 +5,7 @@ public class Panel
     private readonly Tile[,] _tiles;
     private readonly int _width;
     private readonly int _height;
+    private readonly Dictionary<InitialVector, Result> _results = new Dictionary<InitialVector, Result>();
     
     public Panel(Tile[,] tiles)
     {
@@ -13,28 +14,70 @@ public class Panel
         _height = tiles.GetLength(1);
     }
 
-    public int Print()
+    public int Energize(int x, int y, IRay start)
+    {
+        var result = Energize(new InitialVector(x, y, start));
+        Print();
+        return result;
+    }
+
+    public void MaximizeEnergy()
+    {
+        var max = 0;
+        InitialVector? init = null;
+        
+        foreach (var v in InitialVectors())
+        {
+            if (!_results.ContainsKey(v))
+            {
+                var count = Energize(v);
+                if (count > max)
+                {
+                    max = count;
+                    init = v;
+                }
+            }
+        }
+
+        Console.WriteLine($"Initial Vector: {init?.X} / {init?.Y} => {init?.Ray}");
+        Console.WriteLine($"Energized: {max}");
+    }
+    
+    private void Print()
     {
-        var energized = 0;
         Console.WriteLine($"{_width} x {_height}");
         for (var y = 0; y < _height; y++)
         {
             for (var x = 0; x < _width; x++)
             {
-                energized += _tiles[x, y].IsEnergized ? 1 : 0;
                 Console.Write(_tiles[x, y].IsEnergized ? '#' : _tiles[x, y].Value);
             }
             Console.WriteLine();
         }
         Console.WriteLine();
+    }
+    
+    private int Count()
+    {
+        var energized = 0;
+        for (var y = 0; y < _height; y++)
+        {
+            for (var x = 0; x < _width; x++)
+            {
+                energized += _tiles[x, y].IsEnergized ? 1 : 0;
+                _tiles[x, y].Clear();
+            }
+        }
         return energized;
     }
-
-    public void Energize(IRay start, int x, int y)
+    
+    private int Energize(InitialVector vector)
     {
-        var tile = _tiles[x, y];
+        var tile = _tiles[vector.X, vector.Y];
         var stack = new Stack<(IRay Ray, Tile Tile)>();
-        stack.Push((start, tile));
+        stack.Push((vector.Ray, tile));
+        var result = new Result();
+        _results[vector] = result;
 
         while (stack.Count > 0)
         {
@@ -42,16 +85,20 @@ public class Panel
             foreach (var r in item.Tile.Process(item.Ray))
             {
                 var next = Next(r, item.Tile);
-                if (next != null)
+                if (next == null)
+                {
+                    var equivalentInitialVector = new InitialVector(item.Tile.X, item.Tile.Y, r.Rotate().Rotate());
+                    _results[equivalentInitialVector] = result;
+                }
+                else
                 {
                     stack.Push((r, next));
                 }
             }
-
-            Console.WriteLine($"Stack: {stack.Count}");
         }
 
-        Console.WriteLine();
+        result.Energized = Count();
+        return result.Energized;
     }
 
     private Tile? Next(IRay ray, Tile tile)
@@ -61,4 +108,26 @@ public class Panel
             ? _tiles[x, y]
             : null;
     }
+
+    private IEnumerable<InitialVector> InitialVectors()
+    {
+        for (var x = 0; x < _width; x++)
+        {
+            yield return new InitialVector(x, 0, Rays.South);
+            yield return new InitialVector(x, _height - 1, Rays.North);
+        }
+        for (var y = 0; y < _height; y++)
+        {
+            yield return new InitialVector(0, y, Rays.East);
+            yield return new InitialVector(_width - 1, y, Rays.West);
+        }
+    }
+
+    private record InitialVector(int X, int Y, IRay Ray);
+
+    private class Result
+    {
+        public int Energized { get; set; }
+        public IList<InitialVector> InitialVectors { get; } = new List<InitialVector>();
+    }
 }

+ 4 - 2
Day16/Program.cs

@@ -18,8 +18,10 @@ var inputFile = args[0];
 var parser = new Parser();
 var panel = parser.Parse(inputFile);
 
-panel.Energize(Rays.East, 0, 0);
-var energized = panel.Print();
+var energized = panel.Energize(0, 0, Rays.East);
 Console.WriteLine($"Energized: {energized}");
+Console.WriteLine();
+
+panel.MaximizeEnergy();
 
 return 0;

+ 7 - 1
Day16/Tile.cs

@@ -2,7 +2,7 @@
 
 public class Tile
 {
-    private ISet<IRay> _processed = new HashSet<IRay>();
+    private readonly ISet<IRay> _processed = new HashSet<IRay>();
     public int X { get; }
     public int Y { get; }
     public char Value { get; }
@@ -58,4 +58,10 @@ public class Tile
                 break;
         }
     }
+
+    public void Clear()
+    {
+        IsEnergized = false;
+        _processed.Clear();
+    }
 }