diff --git a/01/Trebuchet/Program.cs b/01/Trebuchet/Program.cs
index 46e5e1d..32d2d3f 100644
--- a/01/Trebuchet/Program.cs
+++ b/01/Trebuchet/Program.cs
@@ -1,4 +1,5 @@
-using System.Text.RegularExpressions;
+using System.Diagnostics;
+using System.Text.RegularExpressions;
namespace Trebuchet;
@@ -23,9 +24,15 @@ public class Program
: new PartOnePuzzleSolver();
var input = await File.ReadAllLinesAsync(args[0]);
+
+ var stopwatch = new Stopwatch();
+ stopwatch.Start();
+
var result = puzzleSolver.SumCalibrationValues(input);
- Console.WriteLine($"The sum of all calibration values is {result}.");
+ stopwatch.Stop();
+
+ Console.WriteLine($"The sum of all calibration values is {result}. ({stopwatch.ElapsedMilliseconds}ms)");
return result;
}
diff --git a/08/HauntedWasteland.Tests/GlobalUsings.cs b/08/HauntedWasteland.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..7fef4b0
--- /dev/null
+++ b/08/HauntedWasteland.Tests/GlobalUsings.cs
@@ -0,0 +1,2 @@
+global using Xunit;
+global using FluentAssertions;
\ No newline at end of file
diff --git a/08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj b/08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj
new file mode 100644
index 0000000..ac38c1c
--- /dev/null
+++ b/08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj
@@ -0,0 +1,36 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
+
+
+
+
+
+
+ PreserveNewest
+
+
+
+
diff --git a/08/HauntedWasteland.Tests/MapTests.cs b/08/HauntedWasteland.Tests/MapTests.cs
new file mode 100644
index 0000000..8b307f7
--- /dev/null
+++ b/08/HauntedWasteland.Tests/MapTests.cs
@@ -0,0 +1,118 @@
+namespace HauntedWasteland.Tests;
+
+public class MapTests
+{
+ [Theory]
+ [MemberData(nameof(TestData.ParseMapTestData), MemberType = typeof(TestData))]
+ public void Parse_WhenGivenStringArray_ItShouldReturnMap(string[] input, Map expected)
+ {
+ Map.Parse(input).Should().BeEquivalentTo(expected);
+ }
+
+ [Theory]
+ [MemberData(nameof(TestData.CountStepsTestData), MemberType = typeof(TestData))]
+ public void CountStepsToZ_WhenGivenMap_ItShouldReturnNumberOfSteps(string[] input, int expected)
+ {
+ Map.Parse(input).CountStepsToZ().Should().Be(expected);
+ }
+
+ [Theory]
+ [MemberData(nameof(TestData.CountStepsToAllZNodesData), MemberType = typeof(TestData))]
+ public void CountStepsToAllZNodes_WhenGivenMap_ItShouldReturnNumberOfSteps(string[] input, long expected)
+ {
+ Map.Parse(input).CountStepsToAllZNodes().Should().Be(expected);
+ }
+
+ [Fact]
+ public void FindPrimeFactors_WhenGivenNumber_ItShouldReturnPrimeFactors()
+ {
+ new Map([], []).FindPrimeFactors(11911).Should().BeEquivalentTo([43, 277]);
+ }
+
+ [Fact]
+ public void FindLeastCommonMultiple_WhenGivenNumbers_ItShouldReturnLeastCommonMultiple()
+ {
+ new Map([], []).FindLeastCommonMultiple([16343, 11911, 20221, 21883, 13019, 19667]).Should().Be(13524038372771);
+ }
+
+ public static class TestData
+ {
+ private static readonly string[] MapInput =
+ [
+ "RL",
+ "",
+ "AAA = (BBB, CCC)",
+ "BBB = (DDD, EEE)",
+ "CCC = (ZZZ, GGG)",
+ "DDD = (DDD, DDD)",
+ "EEE = (EEE, EEE)",
+ "GGG = (GGG, GGG)",
+ "ZZZ = (ZZZ, ZZZ)",
+ ];
+
+ private static readonly string[] Input = File.ReadAllLines("INPUT.txt");
+
+ public static IEnumerable