diff --git a/src/08.cs b/src/08.cs new file mode 100644 index 0000000..cb3ccab --- /dev/null +++ b/src/08.cs @@ -0,0 +1,93 @@ +using aoc2024.Util; + +namespace aoc2024; + +internal class Day08 : Day +{ + private readonly Dictionary> antennas = []; + private ivec2 dimensions = ivec2.ZERO; + + internal override void Parse() + { + var lines = Util.Parsing.ReadAllLines($"{GetDay()}").ToList(); + dimensions = new ivec2(lines[0].Length, lines.Count); + for (int i = 0; i < lines.Count; i++) + { + var line = lines[i]; + for (int j = 0; j < line.Length; j++) + { + if (line[j] == '.' || line[j] == '#') + { + continue; + } + + var loc = new ivec2(j, i); + if (!antennas.TryAdd(line[j], [loc])) + { + antennas[line[j]].Add(loc); + } + } + } + } + + internal override string Part1() + { + HashSet antinodes = []; + foreach (var (_, locs) in antennas) + { + foreach (var loc in locs) + { + var others = locs.Except([loc]); + foreach (var other in others) + { + var between = loc - other; + var a1 = loc + between; + var a2 = other - between; + if (a1.IsWithinRange(0, 0, dimensions.x - 1, dimensions.y - 1)) + { + antinodes.Add(loc + between); + } + + if (a2.IsWithinRange(0, 0, dimensions.x - 1, dimensions.y - 1)) + { + antinodes.Add(other - between); + } + } + } + } + + return $"# antinodes: <+white>{antinodes.Count}"; + } + + internal override string Part2() + { + HashSet antinodes = []; + foreach (var (_, locs) in antennas) + { + antinodes.UnionWith(locs); + foreach (var loc in locs) + { + var others = locs.Except([loc]); + foreach (var other in others) + { + var between = loc - other; + var a1 = loc + between; + var a2 = other - between; + while (a1.IsWithinRange(0, 0, dimensions.x - 1, dimensions.y - 1)) + { + antinodes.Add(a1); + a1 += between; + } + + while (a2.IsWithinRange(0, 0, dimensions.x - 1, dimensions.y - 1)) + { + antinodes.Add(a2); + a2 -= between; + } + } + } + } + + return $"# antinodes including harmonics: <+white>{antinodes.Count}"; + } +} diff --git a/src/Util/Vec2.cs b/src/Util/Vec2.cs index 73f955d..254a37b 100644 --- a/src/Util/Vec2.cs +++ b/src/Util/Vec2.cs @@ -74,7 +74,7 @@ public readonly struct ivec2 : IEquatable, IComparable, IComparabl } } - public IEnumerable GetBoundedOrthogonalNeighbors(int minX, int minY, int maxX, int maxY) + public IEnumerable GetBoundedOrthogonalNeighbors(long minX, long minY, long maxX, long maxY) { foreach (var dir in FOURWAY) { @@ -96,7 +96,7 @@ public readonly struct ivec2 : IEquatable, IComparable, IComparabl } } - public IEnumerable GetBoundedNeighbors(int minX, int minY, int maxX, int maxY) + public IEnumerable GetBoundedNeighbors(long minX, long minY, long maxX, long maxY) { foreach (var dir in EIGHTWAY) { @@ -118,7 +118,7 @@ public readonly struct ivec2 : IEquatable, IComparable, IComparabl } } - public IEnumerable GetBoundedDiagonalNeighbors(int minX, int minY, int maxX, int maxY) + public IEnumerable GetBoundedDiagonalNeighbors(long minX, long minY, long maxX, long maxY) { foreach (var dir in DIAGONALS) { @@ -149,17 +149,11 @@ public readonly struct ivec2 : IEquatable, IComparable, IComparabl public static bool operator >(ivec2 a, ivec2 b) => (a.x > b.x) && (a.y > b.y); public static bool operator >=(ivec2 a, ivec2 b) => (a.x >= b.x) && (a.y >= b.y); - public bool IsWithinRange(int minX, int minY, int maxX, int maxY) => x >= minX && y >= minY && x <= maxX && y <= maxY; + public bool IsWithinRange(long minX, long minY, long maxX, long maxY) => x >= minX && y >= minY && x <= maxX && y <= maxY; - public bool Equals(ivec2 other) - { - return x == other.x && y == other.y; - } + public bool Equals(ivec2 other) => x == other.x && y == other.y; - public override bool Equals(object? obj) - { - return obj is ivec2 other && Equals(other); - } + public override bool Equals(object? obj) => obj is ivec2 other && Equals(other); public int CompareTo(ivec2 other) { @@ -178,7 +172,11 @@ public readonly struct ivec2 : IEquatable, IComparable, IComparabl public int CompareTo(object? obj) { - if (ReferenceEquals(null, obj)) return 1; + if (obj is null) + { + return 1; + } + return obj is ivec2 other ? CompareTo(other) : throw new ArgumentException($"Object must be of type {nameof(ivec2)}"); } diff --git a/src/main.cs b/src/main.cs index d64fe15..0884609 100644 --- a/src/main.cs +++ b/src/main.cs @@ -115,12 +115,11 @@ else foreach (var desiredDay in desiredDays) { - Day? day = getDayInstanceFromArg(desiredDay); + using Day? day = getDayInstanceFromArg(desiredDay); if (day == null) { Logger.LogLine($"Unknown day {desiredDay}"); } day?.Go(runPart1 ?? true, runPart2 ?? true); - day?.Dispose(); }