diff --git a/AdventOfCode2024.sln b/AdventOfCode2024.sln
index e3e421e..96318ae 100644
--- a/AdventOfCode2024.sln
+++ b/AdventOfCode2024.sln
@@ -17,6 +17,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Day6", "Day6\Day6.csproj",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Day7", "Day7\Day7.csproj", "{D177FD38-032B-4053-8E84-38368F74CBCE}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Day8", "Day8\Day8.csproj", "{4D1D9998-BA7C-44F9-8305-DBB066485BAF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -51,6 +53,10 @@ Global
{D177FD38-032B-4053-8E84-38368F74CBCE}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D177FD38-032B-4053-8E84-38368F74CBCE}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D177FD38-032B-4053-8E84-38368F74CBCE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4D1D9998-BA7C-44F9-8305-DBB066485BAF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4D1D9998-BA7C-44F9-8305-DBB066485BAF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4D1D9998-BA7C-44F9-8305-DBB066485BAF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4D1D9998-BA7C-44F9-8305-DBB066485BAF}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Day8/Day8.csproj b/Day8/Day8.csproj
new file mode 100644
index 0000000..e0c4c2e
--- /dev/null
+++ b/Day8/Day8.csproj
@@ -0,0 +1,16 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+ Always
+
+
+
+
diff --git a/Day8/Program.cs b/Day8/Program.cs
new file mode 100644
index 0000000..27a8ecd
--- /dev/null
+++ b/Day8/Program.cs
@@ -0,0 +1,196 @@
+var lines = File.ReadAllLines("input.txt");
+var charArray = new char[lines.Length, lines[0].Length];
+
+for (var i = 0; i < charArray.GetLength(0); i++)
+ for (var j = 0; j < charArray.GetLength(1); j++)
+ {
+ charArray[i, j] = lines[i][j];
+ }
+
+var uniqueCharacterPositions = GroupUniqueCharacterPositions(charArray);
+
+var antinodeLocations = new List<(int, int)>();
+var antinodeHarmonicsLocations = new List<(int, int)>();
+
+foreach (var uniqueCharacter in uniqueCharacterPositions)
+{
+ for (var i = 0; i < uniqueCharacter.Value.Count - 1; i++)
+ {
+ var currentPosition = uniqueCharacter.Value[i];
+
+ for (var j = i + 1; j < uniqueCharacter.Value.Count; j++)
+ {
+ var nextPosition = uniqueCharacter.Value[j];
+
+ if (Distance(currentPosition.Item1, currentPosition.Item2, nextPosition.Item1, nextPosition.Item2) >= 1)
+ {
+ antinodeLocations.AddRange(CalculateAntinodes(currentPosition, nextPosition, charArray));
+ }
+
+ antinodeHarmonicsLocations.AddRange(CalculateAntinodesWithHarmonics(currentPosition, nextPosition, charArray));
+ }
+ }
+}
+
+Console.WriteLine(
+ $"Part 1: {antinodeLocations.Distinct().Count()}\nPart 2: {antinodeHarmonicsLocations.Distinct().Count()}");
+
+List<(int, int)> CalculateAntinodesWithHarmonics((int, int) currentPosition, (int, int) nextPosition, char[,] input)
+{
+ var locations = new List<(int, int)>
+ {
+ currentPosition,
+ nextPosition
+ };
+
+ var verticalDistance = Math.Abs(currentPosition.Item1 - nextPosition.Item1);
+ var horizontalDistance = Math.Abs(currentPosition.Item2 - nextPosition.Item2);
+
+ var currentPositionClone = currentPosition;
+ var nextPositionClone = nextPosition;
+ int antinodePositionRow, antinodePositionColumn;
+
+ while (true)
+ {
+ if (currentPositionClone.Item1 < nextPositionClone.Item1)
+ {
+ antinodePositionRow = currentPositionClone.Item1 - verticalDistance;
+ }
+ else
+ {
+ antinodePositionRow = currentPositionClone.Item1 + verticalDistance;
+ }
+
+ if (currentPositionClone.Item2 < nextPositionClone.Item2)
+ {
+ antinodePositionColumn = currentPositionClone.Item2 - horizontalDistance;
+ }
+ else
+ {
+ antinodePositionColumn = currentPositionClone.Item2 + horizontalDistance;
+ }
+
+ if (IsValid(antinodePositionRow, antinodePositionColumn, input))
+ {
+ locations.Add((antinodePositionRow, antinodePositionColumn));
+ nextPositionClone = currentPositionClone;
+ currentPositionClone = (antinodePositionRow, antinodePositionColumn);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ currentPositionClone = currentPosition;
+ nextPositionClone = nextPosition;
+
+ while (true)
+ {
+ if (currentPositionClone.Item1 < nextPositionClone.Item1)
+ {
+ antinodePositionRow = nextPositionClone.Item1 + verticalDistance;
+ }
+ else
+ {
+ antinodePositionRow = nextPositionClone.Item1 - verticalDistance;
+ }
+
+ if (currentPositionClone.Item2 < nextPositionClone.Item2)
+ {
+ antinodePositionColumn = nextPositionClone.Item2 + horizontalDistance;
+ }
+ else
+ {
+ antinodePositionColumn = nextPositionClone.Item2 - horizontalDistance;
+ }
+
+ if (IsValid(antinodePositionRow, antinodePositionColumn, input))
+ {
+ locations.Add((antinodePositionRow, antinodePositionColumn));
+ currentPositionClone = nextPositionClone;
+ nextPositionClone = (antinodePositionRow, antinodePositionColumn);
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ return locations;
+}
+
+List<(int, int)> CalculateAntinodes((int, int) currentPosition, (int, int) nextPosition, char[,] input)
+{
+ var locations = new List<(int, int)>();
+
+ int firstAntinodePositionRow,
+ firstAntinodePositionColumn,
+ secondAntinodePositionRow,
+ secondAntinodePositionColumn;
+
+ var verticalDistance = Math.Abs(currentPosition.Item1 - nextPosition.Item1);
+ var horizontalDistance = Math.Abs(currentPosition.Item2 - nextPosition.Item2);
+
+ if (currentPosition.Item1 < nextPosition.Item1)
+ {
+ firstAntinodePositionRow = currentPosition.Item1 - verticalDistance;
+ secondAntinodePositionRow = nextPosition.Item1 + verticalDistance;
+ }
+ else
+ {
+ firstAntinodePositionRow = currentPosition.Item1 + verticalDistance;
+ secondAntinodePositionRow = nextPosition.Item1 - verticalDistance;
+ }
+
+ if (currentPosition.Item2 < nextPosition.Item2)
+ {
+ firstAntinodePositionColumn = currentPosition.Item2 - horizontalDistance;
+ secondAntinodePositionColumn = nextPosition.Item2 + horizontalDistance;
+ }
+ else
+ {
+ firstAntinodePositionColumn = currentPosition.Item2 + horizontalDistance;
+ secondAntinodePositionColumn = nextPosition.Item2 - horizontalDistance;
+ }
+
+ if (IsValid(firstAntinodePositionRow, firstAntinodePositionColumn, input))
+ {
+ locations.Add((firstAntinodePositionRow, firstAntinodePositionColumn));
+ }
+
+ if (IsValid(secondAntinodePositionRow, secondAntinodePositionColumn, input))
+ {
+ locations.Add((secondAntinodePositionRow, secondAntinodePositionColumn));
+ }
+
+ return locations;
+}
+
+Dictionary> GroupUniqueCharacterPositions(char[,] array)
+{
+ var charLocations = new Dictionary>();
+
+ for (var i = 0; i < array.GetLength(0); i++)
+ {
+ for (var j = 0; j < array.GetLength(1); j++)
+ {
+ var currentChar = array[i, j];
+
+ if (currentChar == '.') continue;
+
+ if (!charLocations.ContainsKey(currentChar))
+ {
+ charLocations[currentChar] = new List<(int, int)>();
+ }
+
+ charLocations[currentChar].Add((i, j));
+ }
+ }
+
+ return charLocations;
+}
+
+bool IsValid(int row, int column, char[,] grid) => row >= 0 && row < grid.GetLength(0) && column >= 0 && column < grid.GetLength(1);
+
+double Distance(int position1Row, int position1Column, int position2Row, int position2Column) => Math.Sqrt(Math.Pow(position1Column - position2Column, 2) + Math.Pow(position2Row - position1Row, 2));
\ No newline at end of file
diff --git a/Day8/input.txt b/Day8/input.txt
new file mode 100644
index 0000000..b19f65d
--- /dev/null
+++ b/Day8/input.txt
@@ -0,0 +1,50 @@
+..........K........................A..............
+.K................................A...............
+......................................D.....A.....
+....................................6............D
+..................................................
+.............................d....................
+.........4.e.......................DT.B...........
+....................d.....D......A...........B....
+.............K....................................
+...........................k......................
+...w..............4.....................y.........
+........w.........................................
+..............g..k..............d..........y......
+.....w.....Q..............................T.......
+...............b..........k................6......
+.................................W...T............
+................w..............BW..T..............
+............g....4e.....................W.........
+.......1.................g.......................W
+........k..........................6.....0........
+.................a................................
+....................4.a........3.g..............7.
+.............m........................I.0.........
+..............K7..............V...................
+....Q................................I............
+..9........b......................I...............
+...................d..............................
+.......e..........................................
+....e...........t..E................3.............
+......1..aQ........t....v.....3..........I..0.....
+...........................v.t.....3.7............
+..........i.......m........M......................
+...Q..29..a...................m...................
+...9......q..........mt...........................
+....1...............Y.....M.........7.............
+..........b..1...E.v..Y...........................
+................v..........q...............0......
+..................E.................5.............
+9...i..2b................................8........
+.....q..2............Y..M.........................
+............q...............................V.....
+...i.................................V............
+.i..............E............M....................
+.........................................G........
+............8................Y....................
+.........2................8..............5........
+......................................5....V......
+............................................G.....
+.....................................5...........G
+.................................8................
\ No newline at end of file