Add day 8

This commit is contained in:
2025-01-24 10:19:11 +01:00
parent 9b865a12b1
commit ef9892502e
2 changed files with 219 additions and 0 deletions

169
Days/Day8.cs Normal file
View File

@@ -0,0 +1,169 @@
using System.Collections.Frozen;
using System.Numerics;
using Spectre.Console;
namespace AdventOfCode.Days;
public class Day8 : Day
{
public override int Number => 8;
public override string Name => "Resonant Collinearity";
private const int GridSize = 50;
public override void RunPart1(bool display = true)
{
HashSet<Point> antinodePositions = [];
var frequencyAntennas = ParseAntennas();
// Find antinodes for each frequency
foreach (var (_, antennas) in frequencyAntennas)
{
// Take antennas by pair to find antinodes
foreach (var firstAntenna in antennas)
{
foreach (var secondAntenna in antennas.Where(a => a != firstAntenna))
{
var firstAntinode = firstAntenna + (firstAntenna - secondAntenna);
var secondAntinode = secondAntenna + (secondAntenna - firstAntenna);
if (firstAntinode is { X: >= 0 and < GridSize, Y: >= 0 and < GridSize })
{
antinodePositions.Add(firstAntinode);
}
if (secondAntinode is { X: >= 0 and < GridSize, Y: >= 0 and < GridSize })
{
antinodePositions.Add(secondAntinode);
}
}
}
}
if (display)
{
AnsiConsole.MarkupLine($"[green]Unique antinode positions count: [yellow]{antinodePositions.Count}[/][/]");
}
}
public override void RunPart2(bool display = true)
{
HashSet<Point> antinodePositions = [];
var frequencyAntennas = ParseAntennas();
// Find antinodes for each frequency
foreach (var (_, antennas) in frequencyAntennas)
{
// Take antennas by pair to find antinodes
foreach (var firstAntenna in antennas)
{
foreach (var secondAntenna in antennas.Where(a => a != firstAntenna))
{
// Always add antinodes on antennas if a pair is formed
antinodePositions.Add(firstAntenna);
antinodePositions.Add(secondAntenna);
// Compute potential antinode positions
var firstAntinodeOffset = firstAntenna - secondAntenna;
var secondAntinodeOffset = secondAntenna - firstAntenna;
for (var i = 1; ; i++)
{
var firstAntinode = firstAntenna + (i * firstAntinodeOffset);
if (firstAntinode is { X: >= 0 and < GridSize, Y: >= 0 and < GridSize })
{
antinodePositions.Add(firstAntinode);
}
else
{
break;
}
}
for (var i = 1; ; i++)
{
var secondAntinode = secondAntenna + (i * secondAntinodeOffset);
if (secondAntinode is { X: >= 0 and < GridSize, Y: >= 0 and < GridSize })
{
antinodePositions.Add(secondAntinode);
}
else
{
break;
}
}
}
}
}
if (display)
{
AnsiConsole.MarkupLine($"[green]Unique antinode positions count: [yellow]{antinodePositions.Count}[/][/]");
}
}
private FrozenDictionary<char, List<Point>> ParseAntennas()
{
var antennas = new Dictionary<char, List<Point>>();
var y = 0;
foreach (var line in Input.AsSpan().EnumerateLines())
{
var x = 0;
foreach (var frequency in line)
{
if (frequency is '.')
{
x++;
continue;
}
if (!antennas.TryGetValue(frequency, out var list))
{
list = [];
antennas[frequency] = list;
}
list.Add(new Point(x, y));
x++;
}
y++;
}
return antennas.ToFrozenDictionary();
}
private readonly record struct Point(int X, int Y)
: IAdditionOperators<Point, Point, Point>,
ISubtractionOperators<Point, Point, Point>,
IMultiplyOperators<Point, int, Point>
{
public static Point operator +(Point left, Point right)
{
return new Point(left.X + right.X, left.Y + right.Y);
}
public static Point operator -(Point left, Point right)
{
return new Point(left.X - right.X, left.Y - right.Y);
}
public static Point operator *(Point left, int right)
{
return new Point(left.X * right, left.Y * right);
}
public static Point operator *(int left, Point right)
{
return new Point(right.X * left, right.Y * left);
}
}
}