mirror of
https://github.com/parnic/advent-of-code-2024.git
synced 2025-06-16 12:30:13 -05:00
Day 8
Took me a little while to understand the problem, but once I did, ivec2 came in clutch once again. Would have had part 2 sooner if not for the "also all antennas are now antinodes" thing which I just missed. You win again, reading comprehension.
This commit is contained in:
93
src/08.cs
Normal file
93
src/08.cs
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
using aoc2024.Util;
|
||||||
|
|
||||||
|
namespace aoc2024;
|
||||||
|
|
||||||
|
internal class Day08 : Day
|
||||||
|
{
|
||||||
|
private readonly Dictionary<char, List<ivec2>> 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<ivec2> 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<ivec2> 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}";
|
||||||
|
}
|
||||||
|
}
|
@ -74,7 +74,7 @@ public readonly struct ivec2 : IEquatable<ivec2>, IComparable<ivec2>, IComparabl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ivec2> GetBoundedOrthogonalNeighbors(int minX, int minY, int maxX, int maxY)
|
public IEnumerable<ivec2> GetBoundedOrthogonalNeighbors(long minX, long minY, long maxX, long maxY)
|
||||||
{
|
{
|
||||||
foreach (var dir in FOURWAY)
|
foreach (var dir in FOURWAY)
|
||||||
{
|
{
|
||||||
@ -96,7 +96,7 @@ public readonly struct ivec2 : IEquatable<ivec2>, IComparable<ivec2>, IComparabl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ivec2> GetBoundedNeighbors(int minX, int minY, int maxX, int maxY)
|
public IEnumerable<ivec2> GetBoundedNeighbors(long minX, long minY, long maxX, long maxY)
|
||||||
{
|
{
|
||||||
foreach (var dir in EIGHTWAY)
|
foreach (var dir in EIGHTWAY)
|
||||||
{
|
{
|
||||||
@ -118,7 +118,7 @@ public readonly struct ivec2 : IEquatable<ivec2>, IComparable<ivec2>, IComparabl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ivec2> GetBoundedDiagonalNeighbors(int minX, int minY, int maxX, int maxY)
|
public IEnumerable<ivec2> GetBoundedDiagonalNeighbors(long minX, long minY, long maxX, long maxY)
|
||||||
{
|
{
|
||||||
foreach (var dir in DIAGONALS)
|
foreach (var dir in DIAGONALS)
|
||||||
{
|
{
|
||||||
@ -149,17 +149,11 @@ public readonly struct ivec2 : IEquatable<ivec2>, IComparable<ivec2>, 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 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)
|
public bool Equals(ivec2 other) => x == other.x && y == other.y;
|
||||||
{
|
|
||||||
return x == other.x && y == other.y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool Equals(object? obj)
|
public override bool Equals(object? obj) => obj is ivec2 other && Equals(other);
|
||||||
{
|
|
||||||
return obj is ivec2 other && Equals(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int CompareTo(ivec2 other)
|
public int CompareTo(ivec2 other)
|
||||||
{
|
{
|
||||||
@ -178,7 +172,11 @@ public readonly struct ivec2 : IEquatable<ivec2>, IComparable<ivec2>, IComparabl
|
|||||||
|
|
||||||
public int CompareTo(object? obj)
|
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)}");
|
return obj is ivec2 other ? CompareTo(other) : throw new ArgumentException($"Object must be of type {nameof(ivec2)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,12 +115,11 @@ else
|
|||||||
|
|
||||||
foreach (var desiredDay in desiredDays)
|
foreach (var desiredDay in desiredDays)
|
||||||
{
|
{
|
||||||
Day? day = getDayInstanceFromArg(desiredDay);
|
using Day? day = getDayInstanceFromArg(desiredDay);
|
||||||
if (day == null)
|
if (day == null)
|
||||||
{
|
{
|
||||||
Logger.LogLine($"Unknown day <cyan>{desiredDay}<r>");
|
Logger.LogLine($"Unknown day <cyan>{desiredDay}<r>");
|
||||||
}
|
}
|
||||||
|
|
||||||
day?.Go(runPart1 ?? true, runPart2 ?? true);
|
day?.Go(runPart1 ?? true, runPart2 ?? true);
|
||||||
day?.Dispose();
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user