diff --git a/Solutions/2024/Day08.cs b/Solutions/2024/Day08.cs index 74b3394..bd59f9b 100644 --- a/Solutions/2024/Day08.cs +++ b/Solutions/2024/Day08.cs @@ -18,12 +18,13 @@ public static void LoadMap(string[] input, Action? visualise = n .ForEachCell() .Where(c => char.IsAsciiLetterOrDigit(c)) .ToLookup(a => a.Value, a => a.Index); + _map.VisualiseMap([], "Initial", visualise); } public static int Part1(string[] _, Action? visualise = null) { - List antinodes = _antennae.GetAntinodes(Antinodes); + List antinodes = _antennae.GetAntinodes(a => a.Antinodes(_map, start: 1)); _map.VisualiseMap(antinodes, "Final", visualise); return antinodes.Count; @@ -31,7 +32,7 @@ public static int Part1(string[] _, Action? visualise = null) public static int Part2(string[] _, Action? visualise = null) { - List antinodes = _antennae.GetAntinodes(a => a.ResidentHarmonicAntinodes(_map)); + List antinodes = _antennae.GetAntinodes(a => a.Antinodes(_map, start: 0)); _map.VisualiseMap(antinodes, "Final", visualise); return antinodes.Count; @@ -39,57 +40,62 @@ public static int Part2(string[] _, Action? visualise = null) private static List GetAntinodes(this ILookup antennae, Func, IEnumerable> antinodesFunc) { - return [..antennae + return [.. + antennae .Select(a => antennae[a.Key]) .Select(antinodesFunc) .SelectMany(antinodes => antinodes) .Distinct() - .Where(antinode => _map.IsInBounds(antinode))]; + ]; } - private static IEnumerable Antinodes(this IEnumerable locations) + private static IEnumerable Antinodes(this IEnumerable locations, char[,] map, int start) { - foreach (IEnumerable item in locations.Combinations(2)) { - Point a1 = item.First(); - Point a2 = item.Last(); - yield return a1 - a2 + a1; - yield return a2 - a1 + a2; + foreach (IEnumerable pair in locations.Combinations(2)) { + Point antenna1 = pair.First(); + Point antenna2 = pair.Last(); + + for (int i = start; ; i++) { + bool outOfBounds = true; + + Point antinode1 = AntinodeN(antenna1, antenna2, i); + if (map.IsInBounds(antinode1)) { + yield return antinode1; + outOfBounds = false; + } + + Point antinode2 = AntinodeN(antenna2, antenna1, i); + if (map.IsInBounds(antinode2)) { + yield return antinode2; + outOfBounds = false; + } + + if (outOfBounds || start == 1) { + break; + } + } } } - private static IEnumerable ResidentHarmonicAntinodes(this IEnumerable locations, char[,] map) - { - foreach (IEnumerable item in locations.Combinations(2)) { - Point a1 = item.First(); - Point a2 = item.Last(); - int i = 0; - while (map.IsInBounds(((a1 - a2) * i) + a1)) { - yield return ((a1 - a2) * i) + a1; - i++; - } + private static Point AntinodeN(Point ant1, Point ant2, int n = 1) => ((ant1 - ant2) * n) + ant1; + + - i = 0; - while (map.IsInBounds(((a2 - a1) * i) + a2)) { - yield return ((a2 - a1) * i) + a2; - i++; - } - } - } public static void VisualiseMap(this char[, ] map, IEnumerable antinodes, string title, Action? visualise) { - char[,] copy = (char[,])map.Clone(); + const char ANTINODE = '#'; + + char[,] vMap = (char[,])map.Clone(); foreach (Point antinode in antinodes) { - copy[antinode.X, antinode.Y] = ANTINODE; + vMap[antinode.X, antinode.Y] = ANTINODE; } if (visualise is not null) { - string[] output = ["", title, .. copy.PrintAsStringArray(0)]; + string[] output = ["", title, .. vMap.AsStrings()]; _ = Task.Run(() => visualise?.Invoke(output, false)); } } - - private const char ANTINODE = '#'; }