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