105 lines
4.7 KiB
C#
105 lines
4.7 KiB
C#
|
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<Char, List<Int32>> antennaLocationsMap = [];
|
|||
|
|
|||
|
while (m.Success)
|
|||
|
{
|
|||
|
if (!antennaLocationsMap.TryGetValue(m.Groups[0].Value[0], out List<int>? 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<Char, HashSet<Int32>> antinodeLocationsMap = [];
|
|||
|
|
|||
|
// set of linear-integer locations of antinodes overall
|
|||
|
HashSet<Int32> overallAntinodeLocations = [];
|
|||
|
|
|||
|
foreach (Char antennaType in antennaLocationsMap.Keys)
|
|||
|
{
|
|||
|
if (!antinodeLocationsMap.TryGetValue(antennaType, out HashSet<int>? 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();
|
|||
|
}
|
|||
|
}
|
|||
|
}
|