|
|
@@ -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>();
|
|
|
+ }
|
|
|
}
|