Part 2 gave me more trouble than it should have, mostly because I was initially turning and stepping at the same time which ended up being a big mistake.

This runs in a few seconds in Debug, but only a half a second in Release. I feel like it can be much faster, but I don't have any ideas on doing that just yet.
This commit is contained in:
2024-12-06 08:34:42 -06:00
parent ed5ca6d763
commit 7c49d88869
2 changed files with 111 additions and 0 deletions

102
src/06.cs Normal file
View File

@ -0,0 +1,102 @@
using aoc2024.Util;
namespace aoc2024;
internal class Day06 : Day
{
private bool[][] grid = [];
private ivec2 startPos;
private ivec2 startDir;
internal override void Parse()
{
var lines = Util.Parsing.ReadAllLines($"{GetDay()}").ToList();
grid = new bool[lines.Count][];
for (int i = 0; i < lines.Count; i++)
{
var line = lines[i];
var row = new bool[line.Length];
for (int j = 0; j < line.Length; j++)
{
if (line[j] == '#')
{
row[j] = true;
}
else
{
row[j] = false;
if (line[j] != '.')
{
startPos = new ivec2(j, i);
startDir = ivec2.DirFromChar(line[j]);
}
}
}
grid[i] = row;
}
}
private (bool, HashSet<ivec2>) HasLoop()
{
var currPos = startPos;
var currDir = startDir;
var loopSet = new HashSet<(ivec2, ivec2)>(10000);
var visited = new HashSet<ivec2>(10000);
while (true)
{
visited.Add(currPos);
if (!loopSet.Add((currPos, currDir)))
{
return (true, visited);
}
var nextPos = currPos + currDir;
if (!nextPos.IsWithinRange(0, 0, grid[0].Length - 1, grid.Length - 1))
{
return (false, visited);
}
if (grid[nextPos.y][nextPos.x])
{
currDir = currDir.GetRotatedRight();
}
else
{
currPos += currDir;
}
}
}
internal override string Part1()
{
var (_, visited) = HasLoop();
return $"Locations visited: <+white>{visited.Count}";
}
internal override string Part2()
{
var (_, allVisited) = HasLoop();
int numBlockedLoops = 0;
foreach (var pos in allVisited)
{
var (x, y) = (pos.x, pos.y);
if (startPos == pos)
{
continue;
}
grid[y][x] = true;
var (hasLoop, _) = HasLoop();
if (hasLoop)
{
numBlockedLoops++;
}
grid[y][x] = false;
}
return $"# obstructions that cause a loop: <+white>{numBlockedLoops}";
}
}

View File

@ -38,6 +38,15 @@ public readonly struct ivec2 : IEquatable<ivec2>, IComparable<ivec2>, IComparabl
public long ManhattanDistance => Abs(this).Sum;
public long ManhattanDistanceTo(ivec2 other) => System.Math.Abs(x - other.x) + System.Math.Abs(y - other.y);
public static ivec2 DirFromChar(char ch) => ch switch
{
'^' => UP,
'>' => RIGHT,
'<' => LEFT,
'v' => DOWN,
_ => throw new FormatException($"Invalid direction {ch}"),
};
public ivec2 GetBestDirectionTo(ivec2 p)
{
ivec2 diff = p - this;