mirror of
https://github.com/parnic/advent-of-code-2024.git
synced 2025-06-16 12:30:13 -05:00
Day 6
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:
102
src/06.cs
Normal file
102
src/06.cs
Normal 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}";
|
||||
}
|
||||
}
|
@ -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;
|
||||
|
Reference in New Issue
Block a user