I solved part 1 the naive way and was reasonably happy with it. I was successfully using that solution with some negative-modulus junk to brute force part 2 (I could get the correct answer for the example data's smaller number of steps), but there was no way it was completing in a reasonable amount of time or without blowing all my RAM. I was at a complete loss for how to solve part 2 the "smart" way, so I learned from this video: https://www.youtube.com/watch?v=9UOMZSL0JTg

I understand why this works now, but I was not going to be getting it on my own (nor did I really want to spend the time it would have taken me to attempt to arrive at a similar solution).
This commit is contained in:
2023-12-21 09:50:37 -06:00
parent 11fc463922
commit bf16614487
4 changed files with 277 additions and 0 deletions

View File

@ -73,6 +73,8 @@
<EmbeddedResource Include="inputs\20.txt" />
<EmbeddedResource Include="inputs\20a.txt" />
<EmbeddedResource Include="inputs\20b.txt" />
<EmbeddedResource Include="inputs\21.txt" />
<EmbeddedResource Include="inputs\21a.txt" />
</ItemGroup>
<ItemGroup>

131
inputs/21.txt Normal file
View File

@ -0,0 +1,131 @@
...................................................................................................................................
..#...#....#.......#.#..##......#...............#..#....#......................................#....##.........#...##..#.#.....#...
.....#..#............#....#.#...##..#.................#..#..................#...#.#.......#.#..#....#.....#...#.#..............#...
.#........#...........#......................#..........#................#...#..............#......#...........#..#.....#.#........
..#.#.#..........#.......#....#....#......#.......#...#..................#.###...........#...........##...#..........#.##.#.#.#.#..
.#.#.........#.....#.#...........#.......##.###.....#.#.........#.#.........##.................##.........##.#.............##.#....
...#.#...#.#...........#.#.####....................##.#........##..........#......#.............##.#...............#...............
......##...#.##....#.......#....#...#....#..................................#......#.#.#..#.........#..........#..#...#............
.#..#..#...#........................#......#...##.................#...............#..........##.........#..........................
......#...#..#...#................#....#.....................#..................#...#.............#..#..#.......##.#.....#.........
.#........#..........#...#........#...........##..............#...#..#.................#............................#.....#....#...
...............##..####...........###..#...##.#................#.......#.................#......#........................#......#..
....#............#.........#...........#..#.#.#..........#..........#...............#....#....###...##.........#...................
.#.....#..#....#.#..............#..#.....#.#........................................##..#.....#....#...#..##.##...#................
.....#.....#....#..#......#...............#....#.......#..#..............#...................#............................#........
................#........#................#.#.........................#.....#.......#.....#.................#.....#.........#......
......##....#..#...#....#..#............#....#...........#..##............#..#.........#.......#...#.#..........#.....#...#....#...
....#.#...#.........#..#....#...#......#................#..##.......##.................#..#....#..........#......#.................
..........#..#..#..#..........#........................#.................###..............##.#..#.#......#...#.##...........#......
.###...#.......#..................#....#...............#.......#..#..#...#..#.......................#.#...#..#........#...#......#.
.......#...........#.#..##......#................#............#.#.#......#................#.........#.....#..........#..#..#...#...
....#.....................##....#......##...................#...............#.....#...............#..#........#.#....##.....#..#...
.......#..#.##..#...###...#........#.............##........#......................##.........#...............#....#.#..............
..###.......#..#......#........#...#...............###.###.........#.#.#........#...........#.........#...........#....#....#.#....
.....#..........#......#...#.........#........#........#...#...........#.....#.#.............................#.#.......###.##.#.##.
..#.................#.............#................#.#............#.#.....#........................#........#.................#....
.#..##..#.#......##..........................#..#.........#.....#......#.....#.....#............................###.....##....#..#.
.......#.#.......#............#...........#....#.......#....#...............#.#..##..##.........#....#..............#....###...#...
...#.......#..##..#..#......................#......##......#........#...#........##.##.#..................#...#.#....##..##......#.
...#.......#.........#.........................#...................#......#.......#...#...#.......#............#........###........
.#.#.#...#.#........##..................#...#.#.........................#......#.....#..#.#........##............#...........#.....
.#.#...#.....###.#........##...........#..#...##.........#...###..#.#...#....##........#...#.............#...#........##...#.....#.
..............#..........#...#........#.......##..##........................#................#........##.........#.................
....##.................#..................................#.............##..#.#....#...#..#...................#.....#....#.#.#.....
....#####...##...#..##..#..#.......###.....#.#......#..#..#.##.....#..#.................#..........................#.#.##.#........
..........#..#....##.#.................#......#...#.#.......#......##.........#..#.#.....................................#..#......
..##..##.....#.....#....#...........#.#..........#............#.......###....................#..#..........#....#............#...#.
......#..........#.......................#...#......#...#...#..#....#..#.....#...........#..#....#............#.....#....#.#.......
.#..#......#...#..##................##..#...#.........#.........#.#..#..................#..........................#...#..#.##.....
..#......#..#..................................#.....#.###.#.........#......#.#...#................#..........#....#...............
........#..##....#...................#........#....#...#..........#...#...#..........####.....#..##.#................#.........###.
....#..............................#..#..#..#.##......#...#...................#.##..........#..#...#..................#....###.##..
.#..........................#.#..#...........#..#......#..#..#........................#........................##...#.#..#......#..
............................#..#...#..................#................#..............##.#.#.#..................#...........##.#...
.........#..###............#.....##...#..#...#.##.....##....#.....#.#.......#.#...#........##.........#.#..............#.#.....#...
...........#............#.........#.....##...##......#.........#...##...............#.##................#............#.....#...#...
.#####.#..#...............................#..#...............#...................#.....#.#............#................#...#.......
.#..#...#....#....................#...........#.................................................#......##................#....##.#.
....#......#..........#..##...#..#.##....#...#.....#.#........#...#.....#.....#......#...#..#..#..#........................#....#..
...#.....#..........##......#..#.....##...#...#...#.#..........#..............#.....#..........#..#.....###.................###....
.....................##...#....#....#......#...#.#.......#...........#..........#..............#.......##.................#..#.....
..##.................#.......#...........#.##........#..##.#...........#.#....#.#.......#..##....#.#..#....#....#..................
.....#...........#.#........#..........#..#.##.....#............#.......#..#.....##....#.#...........##.......#............#.......
.....##.#.............##........##...........#..#.#..##.#.......#.......#..................#.#..#..#.......#.................#.#...
.#.#..............##....#.......#......#..#........#..................#.#.##..#...#....#.#...........##.....#..#..#.........##.....
..............##................#....#....#........#.......#...##...#.#.#........#.#...#...#..#.#.......#.#...#....................
.............####.....#..........................#.#..................................#........#.#..##...#...#..#..................
.#......................#.....#####.#...........#.#............#.............##....#....#.#...........##..........##...........##..
...........#.#.#..#...##...##........#.......#.......#.#........#.......#......#............#..###....#.......#..#.....#........#..
............#....#...............#.##............#...##....#.#...........#........#...#...##...........#..........#................
......................#............#..##......#......#....#.......#..##......#...#....#....#....#..#..#..........#.....#.#.........
................#.....##.......#....##..#.......#......###......#.......#....#.......#....##...........#.#....#....##....#.........
................#..#...#.##...#...#....#.........#....#...##......#.#...#....#.............#.....#............##...#...............
......................#....#......#.#....##...#...#...#.#.......#.....#..#.......#...#.#.##..#........#.....#....#.........#.......
.....##..#..#......................#.#........#....#......#....#..#....#.........#..#.......#.......#.......#.#.......#.###..#.....
.................................................................S.................................................................
..................#...#.....#....#...........#..#.#..........#............................#....................##.....#....#.......
.........#....#......#..#......#...#.#......#...#...#..............#....##.##........#..........##...##...#.......##.#....#........
................#.##.#..#..............#.....#..#......#....#............#.#...###..#......#......#....#........#..##..............
.........#.....................................#...#.#.............#.....#...........#........###.....................#.#..........
.........#....#...........#...##..#........#..........#.#.....#.................#.#.#.##..#...#.#................#....#............
...................#...................#...#..............#.....#.#.......#..............#......#..........###.......#..#..........
...........#.#.............##...#...#....#.#.....#....................#.....#..#.....#........##.#....#....#...................##..
.#................#.#.#.##.............#..#...#....#.#..####.#.......##......................#.......#....#....##................#.
...##..............###...#.#..#..#.#...................#....#...#..#.#....##.....#.....#........#...#...#.#.#...................##.
................................##.#..........#........#..........#.#....#.........##.......##........#............................
...#............##......#.........#.....#.#................##......#.......#....##...#....#.....#.#..#....#.#.....#.............#..
......#.........#.....###.##...#..#...#..#.##....#.#.....#.#.#........##...#..#..........#.............#...................#.......
.#....#............#.....#..##....##...##.....#.#......##..#........#..........#.................#.......#......#.............#....
...#.....#........#......#...........#..#......#.#.#...#....#.###.....##...##..#...#......#..#..........#..#..#..........#.....#...
..#.#..#...........#.###...#.......#..........#...#.........#.#....#......#.........#...#....#...#.##....#....#..........##....#...
......#.#...#............##.......#.......##...............#..................#.#....#..#..#..#..#...#...#...#.....................
....#.......................#........##..#........##.....#.............#........#.#...........#.....#....##...........#..#.........
...#.......#..#.......#......#....#......#..........#.#.#.#.......##....#....................##.........#................#..#......
..#....................###.......##.#.....#.....#.#............##..#....#..#.................#...#..##.###............#...#..##....
.....#......#..#...............#.....##......#.....#.......#..#.#..#....#..##.................##....#....##................#....#..
.............##..#.........#..#..#........#..#..........#...#................###..........##.#.#.........#........#....##..#..#....
.#.#.#.......#..............#....#...#............#.......#....#.........#........#....#............#............#...#.#..#........
.............#.....#.........................#....#.#...........#.................#.#..#....#..........................#.##...#....
...#......#........#.............#..................#.###....................#.#.....#........#.....#.........#.#.#.....#.#........
.#.............#...##...........#.....#.....#.............#.........#...............###....#...#..#.#............#.#.............#.
............##..#................#....#.......#............##.........##..................#......................#.#..#....#.......
............#......#.....................#.#.#.#..#.#..#......#.............#.#....##.....#....#...............#.#............#....
..#..#.#.#.#....#......#............##..............#....##.........#.......#.....#...##.....#....................#.......#.....#..
...#...........#.......#...................#......#...#.##....##....#..#.#...##..#..........#...##............#..#........#.....#..
.....#....#..#..##................#...#...#....#.#....#.#.............#...#..............#.##.............#..#..#....#.#...#...#.#.
.......#..#.........#.....#..........#......#.#...#.........#.#.....#...#..........#....................#....#..........#..........
..#.#.#.....#.........#..###...........#.##.#.......#..#..........#.#.......#......#......#.#.........#.#....#..#..#.......#....#..
.#.........#...#......#...............#......#.#.....#.....................#.......#.#......#..................#...............##..
..#....#..............................#.....#.##.....#........#....#......#....#....#..#....#........###..#..#..........#....#..#..
....#.......##........##..............................#.........#...###.#........#...#.##.............##.....#.#......#..........#.
...#.#.##.....#........#.................#...#..#........#............#..#.#........#....................#.....#........#..........
.........#....#.........#.......##...........#.#.#.#..............#......#..#.......................#.#......................#.....
............#........#..##..#................#..#.............#.............####....#..#.........#............................#....
....#......#..##...#...#.#...................#.....#.....#.........#.............#...............#...............###.......#.#.....
.#.....#..........................#...........#...............#............##......#.#..........#.......#..........................
...##.....................#....#...#.........#...............#..#......##.#...#.#..................#.......#.......................
...#........#....#....................#............#.#...#...............#................................##..........##....#.#....
.#...##.....#........####....#......#.#......................#.............#..#....#.......#...........#..#.........#..............
......#..............#...........#..##.....................#.#.......#.#..###.............#......#.......#..#...#...............#..
...#....#...................##...................#.#.#.#...##.....#.#.......#.#..........#............#..............##.......#....
...........#.................##.........#..............#.......##..##..#.#................##.#.#..#.#.#.............#..............
........#..##.....#.#.......#.........................#....##.........###.....##........#..........#..#...#............#...#....#..
...................#.#.#......#..#.........#............#..#........#........#............#....#...........#.......................
.......#..........#.............#.#.#..#....#...............#..............#...........##..#...#..................#..........##..#.
..............##....#....#..#.....#..........#.........#.#...#.....###..#.............#...................#..#.#.#....##..#....#...
...##..........#.....#.#.#...##...#...#........#............#........#.#..............#.....#........#..##...........#.#........#..
.#..#.#....#..##.##....##.#....##....#...#...#..........#..##.......#...................#.......##..........#........#...#.#....#..
.#..#....#........#......#...............###.............#..........#...#...............#........#...#...###....#..#.#.........#...
.....#.........#.#..#....#...#.....#......#.................#...#....#...............#.........#.........#...........#.#...........
..##.....#..........#...#..#.....#....#.#.....................#...#.................#.....#..#...#.#................#.........##.#.
.........#..#.##........#...####......#.......#................#...#............#..#.#...........#....#.....#.#....#...###.........
.........#......#...#...#....#...#.....##..#..##.....#..............#........#........#.........#...........#.....#......#.#..#....
...##.......#.....#....#.............#.##...#.#....................................#.#...#...............#...................#.....
......................#.###.............#........#.................................#.##........#..#.#.............##...#...........
...#........#....#.....#.#...........#.#.......#....#.............#................#.....#..#..#..#.#.......#...#.....#.....##.....
.##.#....#.........#........##......#................##............................#...#..................#...##............##.....
......#.......#........#..#.#...#.........#............#.#........................#..#....#.#...##.........#...#..........##.......
............#.#...#.....#..#..........#.....#..........................###.#.......##..#......#...#......#.........##...###.....#..
.#.#......#.#..............#............#..........#.#....................#......#..#...#....#..#.#......#...............#.#.......
...................................................................................................................................

11
inputs/21a.txt Normal file
View File

@ -0,0 +1,11 @@
...........
.....###.#.
.###.##..#.
..#.#...#..
....#.#....
.##..S####.
.##..#...#.
.......##..
.##.#.####.
.##..##.##.
...........

133
src/21.cs Normal file
View File

@ -0,0 +1,133 @@
using aoc2023.Util;
namespace aoc2023;
internal class Day21 : Day
{
private int width;
private int height;
private readonly HashSet<ivec2> garden = [];
private ivec2 start = new(0, 0);
internal override void Parse()
{
var lines = Parsing.ReadAllLines($"{GetDay()}").ToList();
height = lines.Count;
for (int y = 0; y < height; y++)
{
width = lines[y].Length;
for (int x = 0; x < width; x++)
{
if (lines[y][x] == '.' || lines[y][x] == 'S')
{
var pt = new ivec2(x, y);
garden.Add(pt);
if (lines[y][x] == 'S')
{
start = pt;
}
}
}
}
}
private long FillGrid(long startY, long startX, long steps)
{
HashSet<(long, long)> filled = [];
HashSet<(long, long)> visited = [];
Queue<(long y, long x, long step)> q = [];
q.Enqueue((startY, startX, steps));
while (q.TryDequeue(out (long y, long x, long step) currLoc))
{
if (currLoc.step % 2 == 0)
{
filled.Add((currLoc.y, currLoc.x));
}
if (currLoc.step == 0)
{
continue;
}
foreach (var (newY, newX) in ((long, long c)[]) [(currLoc.y + 1, c: currLoc.x), (currLoc.y - 1, c: currLoc.x), (currLoc.y, currLoc.x + 1), (currLoc.y, currLoc.x - 1)])
{
if (newY < 0 || newY >= height || newX < 0 || newX >= width || !garden.Contains(new ivec2(newY, newX)) ||
!visited.Add((newY, newX)))
{
continue;
}
q.Enqueue((newY, newX, currLoc.step - 1));
}
}
return filled.Count;
}
internal override string Part1()
{
HashSet<ivec2> next = [start];
HashSet<ivec2> reachableNow = [];
const int numSteps = 64;
for (int step = 0; step < numSteps; step++)
{
HashSet<ivec2> curr = [..next];
next.Clear();
foreach (var pos in curr)
{
foreach (var neighbor in pos.GetBoundedOrthogonalNeighbors(0, 0, width, height))
{
if (!garden.Contains(neighbor))
{
continue;
}
if (step == numSteps - 1)
{
reachableNow.Add(neighbor);
}
next.Add(neighbor);
}
}
}
long numVisited = reachableNow.Count;
return $"<+white>{numVisited}";
}
internal override string Part2()
{
const long steps = 26501365;
long gridWidth = steps / width - 1;
long odd = (long)System.Math.Pow(gridWidth / 2 * 2 + 1, 2);
long even = (long)System.Math.Pow((gridWidth + 1) / 2 * 2, 2);
long oddPoints = FillGrid(start.y, start.x, width * 2 + 1);
long eventPoints = FillGrid(start.y, start.x, width * 2);
long cornerTop = FillGrid(width - 1, start.x, width - 1);
long cornerRight = FillGrid(start.y, 0, width - 1);
long cornerBottom = FillGrid(0, start.x, width - 1);
long cornerLeft = FillGrid(start.y, width - 1, width - 1);
long smallTopRight = FillGrid(width - 1, 0, width / 2 - 1);
long smallTopLeft = FillGrid(width - 1, width - 1, width / 2 - 1);
long smallBottomRight = FillGrid(0, 0, width / 2 - 1);
long smallBottomLeft = FillGrid(0, width - 1, width / 2 - 1);
long largeTopRight = FillGrid(width - 1, 0, width * 3 / 2 - 1);
long largeTopLeft = FillGrid(width - 1, width - 1, width * 3 / 2 - 1);
long largeBottomRight = FillGrid(0, 0, width * 3 / 2 - 1);
long largeBottomLeft = FillGrid(0, width - 1, width * 3 / 2 - 1);
long numVisited = odd * oddPoints +
even * eventPoints +
cornerTop + cornerRight + cornerBottom + cornerLeft +
(gridWidth + 1) * (smallTopRight + smallTopLeft + smallBottomRight + smallBottomLeft) +
gridWidth * (largeTopRight + largeTopLeft + largeBottomRight + largeBottomLeft);
return $"<+white>{numVisited}";
}
}