using System; using System.Collections.Generic; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading.Tasks; using System.Text.RegularExpressions; namespace Advent24 { internal class Day8 { public Day8() { String fileData = System.IO.File.ReadAllText(@"..\..\..\inputd8.txt"); // set this to false for part 1 Boolean enableResonantHarmonics = true; // get width of line to be able to navigate the map block in // both dimensions Int32 mapWidth = fileData.IndexOf('\n'); Int32 mapWidthIncludingNewline = mapWidth + 1; String pattern = @"[A-Za-z0-9]"; Regex r = new(pattern, RegexOptions.Multiline, TimeSpan.FromMilliseconds(150)); Match m = r.Match(fileData); // list of linear-integer locations of antennas indexed by antenna type (a single alphanumeric character) Dictionary> antennaLocationsMap = []; while (m.Success) { if (!antennaLocationsMap.TryGetValue(m.Groups[0].Value[0], out List? antennaLocations)) antennaLocationsMap.Add(m.Groups[0].Value[0], [m.Groups[0].Index]); else antennaLocationsMap[m.Groups[0].Value[0]].Add(m.Groups[0].Index); // Console.WriteLine("antennaLocationsMap[{0:d}] = {1:d}", m.Groups[0].Value[0], antennaLocationsMap[m.Groups[0].Value[0]].Last()); m = m.NextMatch(); } // set of linear-integer locations of antinodes indexed by antenna type (single-character alphanumeric) Dictionary> antinodeLocationsMap = []; // set of linear-integer locations of antinodes overall HashSet overallAntinodeLocations = []; foreach (Char antennaType in antennaLocationsMap.Keys) { if (!antinodeLocationsMap.TryGetValue(antennaType, out HashSet? antinodeLocations)) antinodeLocationsMap.Add(antennaType, []); // for each (ordered) pair of antennaLocations of the same antenna type, we'll construct an antinode // and then add it to the antinodeLocationsMap (keyed by antenna type) foreach(Int32 antennaLocation1 in antennaLocationsMap[antennaType]) foreach(Int32 antennaLocation2 in antennaLocationsMap[antennaType]) { if (antennaLocation1 == antennaLocation2) continue; Int32 antennaLocationDifference = antennaLocation2 - antennaLocation1; Int32 antennaLocationXDifference = (antennaLocation2 % mapWidthIncludingNewline) - (antennaLocation1 % mapWidthIncludingNewline); Int32 antinodeLocation = antennaLocation2; do { Int32 antinodePreviousLocationX = antinodeLocation % mapWidthIncludingNewline; antinodeLocation += antennaLocationDifference; Int32 antinodeLocationXDifference = (antinodeLocation % mapWidthIncludingNewline) - antinodePreviousLocationX; // bounds checking if ( antinodeLocation < 0 || antinodeLocation >= fileData.Length || fileData[antinodeLocation] == '\n' || // x-direction having changed implies we crossed the right/left boundary ((antennaLocationXDifference > 0) != (antinodeLocationXDifference > 0)) ) break; antinodeLocationsMap[antennaType].Add(antinodeLocation); } while (enableResonantHarmonics); if(enableResonantHarmonics) { antinodeLocationsMap[antennaType].Add(antennaLocation1); antinodeLocationsMap[antennaType].Add(antennaLocation2); } } // adding to the overall antinode location set overallAntinodeLocations = [.. overallAntinodeLocations, .. antinodeLocationsMap[antennaType]]; } Int32 numberOfUniqueAntinodeLocations = overallAntinodeLocations.Count; Console.WriteLine("numberOfUniqueAntinodeLocations = {0:d}", numberOfUniqueAntinodeLocations); // to keep the console window from closing Console.ReadKey(); } } }