From 1506d716fbcbddf6ab0cc6277ae62c6923369c9f Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Fri, 8 Dec 2023 15:47:07 -0600 Subject: [PATCH 1/6] chore: scaffold for day 8 puzzle --- 08/HauntedWasteland.Tests/GlobalUsings.cs | 2 ++ .../HauntedWasteland.Tests.csproj | 30 +++++++++++++++++++ 08/HauntedWasteland.Tests/UnitTest1.cs | 10 +++++++ 08/HauntedWasteland/HauntedWasteland.csproj | 10 +++++++ 08/HauntedWasteland/Program.cs | 2 ++ AdventOfCode2023.sln | 16 ++++++++++ 6 files changed, 70 insertions(+) create mode 100644 08/HauntedWasteland.Tests/GlobalUsings.cs create mode 100644 08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj create mode 100644 08/HauntedWasteland.Tests/UnitTest1.cs create mode 100644 08/HauntedWasteland/HauntedWasteland.csproj create mode 100644 08/HauntedWasteland/Program.cs 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..b77aed5 --- /dev/null +++ b/08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj @@ -0,0 +1,30 @@ + + + + net8.0 + enable + enable + + false + true + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + diff --git a/08/HauntedWasteland.Tests/UnitTest1.cs b/08/HauntedWasteland.Tests/UnitTest1.cs new file mode 100644 index 0000000..a3f19b5 --- /dev/null +++ b/08/HauntedWasteland.Tests/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace HauntedWasteland.Tests; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + + } +} \ No newline at end of file diff --git a/08/HauntedWasteland/HauntedWasteland.csproj b/08/HauntedWasteland/HauntedWasteland.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/08/HauntedWasteland/HauntedWasteland.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/08/HauntedWasteland/Program.cs b/08/HauntedWasteland/Program.cs new file mode 100644 index 0000000..3751555 --- /dev/null +++ b/08/HauntedWasteland/Program.cs @@ -0,0 +1,2 @@ +// See https://aka.ms/new-console-template for more information +Console.WriteLine("Hello, World!"); diff --git a/AdventOfCode2023.sln b/AdventOfCode2023.sln index e11e266..bc2abf3 100644 --- a/AdventOfCode2023.sln +++ b/AdventOfCode2023.sln @@ -45,6 +45,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CamelCards", "07\CamelCards EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CamelCards.Tests", "07\CamelCards.Tests\CamelCards.Tests.csproj", "{8F04A78E-D2E1-41AC-B43C-74608B7B4FCB}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "08", "08", "{F21CCF39-1F8A-40DA-A0E5-F1426B09BAA2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HauntedWasteland", "08\HauntedWasteland\HauntedWasteland.csproj", "{332B56C1-8ECB-4E34-9E69-54BF6A192CFB}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HauntedWasteland.Tests", "08\HauntedWasteland.Tests\HauntedWasteland.Tests.csproj", "{FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -110,6 +116,14 @@ Global {8F04A78E-D2E1-41AC-B43C-74608B7B4FCB}.Debug|Any CPU.Build.0 = Debug|Any CPU {8F04A78E-D2E1-41AC-B43C-74608B7B4FCB}.Release|Any CPU.ActiveCfg = Release|Any CPU {8F04A78E-D2E1-41AC-B43C-74608B7B4FCB}.Release|Any CPU.Build.0 = Release|Any CPU + {332B56C1-8ECB-4E34-9E69-54BF6A192CFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {332B56C1-8ECB-4E34-9E69-54BF6A192CFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {332B56C1-8ECB-4E34-9E69-54BF6A192CFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {332B56C1-8ECB-4E34-9E69-54BF6A192CFB}.Release|Any CPU.Build.0 = Release|Any CPU + {FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {3F8EAC09-4BC7-43AA-B72B-48DDD2710F6D} = {8C29858C-623A-461A-BF0B-254E151CD9C2} @@ -126,5 +140,7 @@ Global {8C89E1D0-2617-4B89-BA9C-9189FC69BC43} = {86704890-D6B8-4166-853B-F1424B8396C7} {DC16CBE1-B1FA-4E6B-AAD8-43CDECA46659} = {7F8AD027-D8D7-407B-9E08-B363B7B34621} {8F04A78E-D2E1-41AC-B43C-74608B7B4FCB} = {7F8AD027-D8D7-407B-9E08-B363B7B34621} + {332B56C1-8ECB-4E34-9E69-54BF6A192CFB} = {F21CCF39-1F8A-40DA-A0E5-F1426B09BAA2} + {FA8DDDD1-4DD9-4927-A9FB-C4FACDEAF901} = {F21CCF39-1F8A-40DA-A0E5-F1426B09BAA2} EndGlobalSection EndGlobal From b05f886666d272bb03e1dbb5e6169819ee35d63d Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Fri, 8 Dec 2023 21:46:28 -0600 Subject: [PATCH 2/6] feat: solve part 1 --- 01/Trebuchet/Program.cs | 11 ++- 08/HauntedWasteland.Tests/MapTests.cs | 65 +++++++++++++++ 08/HauntedWasteland.Tests/NodeTests.cs | 54 +++++++++++++ 08/HauntedWasteland.Tests/UnitTest1.cs | 10 --- 08/HauntedWasteland/Program.cs | 108 ++++++++++++++++++++++++- 5 files changed, 234 insertions(+), 14 deletions(-) create mode 100644 08/HauntedWasteland.Tests/MapTests.cs create mode 100644 08/HauntedWasteland.Tests/NodeTests.cs delete mode 100644 08/HauntedWasteland.Tests/UnitTest1.cs 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/MapTests.cs b/08/HauntedWasteland.Tests/MapTests.cs new file mode 100644 index 0000000..6373d76 --- /dev/null +++ b/08/HauntedWasteland.Tests/MapTests.cs @@ -0,0 +1,65 @@ +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.CountTurnsTestData), MemberType = typeof(TestData))] + public void CountStepsToZ_WhenGivenMap_ItShouldReturnNumberOfSteps(string[] input, int expected) + { + Map.Parse(input).CountStepsToZ().Should().Be(expected); + } + + 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)", + ]; + + public static IEnumerable CountTurnsTestData => + new List + { + new object[] + { + MapInput, + 2 + }, + }; + + public static IEnumerable ParseMapTestData => + new List + { + new object[] + { + MapInput, + new Map( + ['R', 'L'], + [ + new("AAA", "BBB", "CCC"), + new("BBB", "DDD", "EEE"), + new("CCC", "ZZZ", "GGG"), + new("DDD", "DDD", "DDD"), + new("EEE", "EEE", "EEE"), + new("GGG", "GGG", "GGG"), + new("ZZZ", "ZZZ", "ZZZ"), + ] + ) + }, + }; + } +} \ No newline at end of file diff --git a/08/HauntedWasteland.Tests/NodeTests.cs b/08/HauntedWasteland.Tests/NodeTests.cs new file mode 100644 index 0000000..4a3fcca --- /dev/null +++ b/08/HauntedWasteland.Tests/NodeTests.cs @@ -0,0 +1,54 @@ +namespace HauntedWasteland.Tests; + +public class NodeTests +{ + [Theory] + [MemberData(nameof(TestData.ParseNodeTestData), MemberType = typeof(TestData))] + public void Parse_WhenGivenString_ItShouldReturnNode(string input, Node expected) + { + Node.Parse(input).Should().BeEquivalentTo(expected); + } + + public static class TestData + { + public static IEnumerable ParseNodeTestData => + new List + { + new object[] + { + "AAA = (BBB, CCC)", + new Node("AAA", "BBB", "CCC") + }, + new object[] + { + "BBB = (DDD, EEE)", + new Node("BBB", "DDD", "EEE") + }, + new object[] + { + "CCC = (ZZZ, GGG)", + new Node("CCC", "ZZZ", "GGG") + }, + new object[] + { + "DDD = (DDD, DDD)", + new Node("DDD", "DDD", "DDD") + }, + new object[] + { + "EEE = (EEE, EEE)", + new Node("EEE", "EEE", "EEE") + }, + new object[] + { + "GGG = (GGG, GGG)", + new Node("GGG", "GGG", "GGG") + }, + new object[] + { + "ZZZ = (ZZZ, ZZZ)", + new Node("ZZZ", "ZZZ", "ZZZ") + }, + }; + } +} \ No newline at end of file diff --git a/08/HauntedWasteland.Tests/UnitTest1.cs b/08/HauntedWasteland.Tests/UnitTest1.cs deleted file mode 100644 index a3f19b5..0000000 --- a/08/HauntedWasteland.Tests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace HauntedWasteland.Tests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - - } -} \ No newline at end of file diff --git a/08/HauntedWasteland/Program.cs b/08/HauntedWasteland/Program.cs index 3751555..9f7c8a1 100644 --- a/08/HauntedWasteland/Program.cs +++ b/08/HauntedWasteland/Program.cs @@ -1,2 +1,106 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); +using System.Diagnostics; + +namespace HauntedWasteland; + +public class Program +{ + public static async Task Main(string[] args) + { + if (args.Length is 0) + { + Console.WriteLine("Please provide a path to the input file."); + return -1; + } + + if (File.Exists(args[0]) is false) + { + Console.WriteLine("The provided file does not exist."); + return -2; + } + + var input = await File.ReadAllLinesAsync(args[0]); + + var stopwatch = new Stopwatch(); + stopwatch.Start(); + + var result = Map.Parse(input).CountStepsToZ(); + + stopwatch.Stop(); + + Console.WriteLine($"The number of steps to Z is {result}. ({stopwatch.ElapsedMilliseconds}ms)"); + + return result; + } +} + +public class Map( + List turns, + List nodes +) +{ + public List Turns { get; init; } = turns; + public List Nodes { get; init; } = nodes; + + public static Map Parse(string[] mapInput) + { + var turns = mapInput[0].ToList(); + var nodes = mapInput[2..] + .Select(Node.Parse) + .ToList(); + + return new Map(turns, nodes); + } + + public int CountStepsToZ() + { + var current = Nodes.First(n => n.Current == "AAA"); + var steps = 0; + + while (current.Current != "ZZZ") + { + var next = Turns[steps % Turns.Count] switch + { + 'R' => current.Right, + 'L' => current.Left, + _ => throw new Exception("Invalid turn") + }; + current = Nodes.First(n => n.Current == next); + steps++; + } + + return steps; + } +} + +public class Node( + string current, + string left, + string right +) +{ + public string Current { get; init; } = current; + public string Left { get; init; } = left; + public string Right { get; init; } = right; + + public override string ToString() + { + return $"{Current} = ({Left},{Right})"; + } + + public static Node Parse(string nodeString) + { + var parts = nodeString.Split( + '=', + StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries + ); + var current = parts[0]; + var nextNodes = parts[1].Split( + ',', + StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries + ); + var left = nextNodes[0].Trim('('); + var right = nextNodes[1].Trim(')'); + + return new Node(current, left, right); + } +} \ No newline at end of file From 9aff5620f07d12fd313fde3fa0f62795040fe659 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Fri, 8 Dec 2023 22:01:58 -0600 Subject: [PATCH 3/6] tests: add input file as test case --- 08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj | 6 ++++++ 08/HauntedWasteland.Tests/MapTests.cs | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj b/08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj index b77aed5..ac38c1c 100644 --- a/08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj +++ b/08/HauntedWasteland.Tests/HauntedWasteland.Tests.csproj @@ -27,4 +27,10 @@ + + + PreserveNewest + + + diff --git a/08/HauntedWasteland.Tests/MapTests.cs b/08/HauntedWasteland.Tests/MapTests.cs index 6373d76..92462b2 100644 --- a/08/HauntedWasteland.Tests/MapTests.cs +++ b/08/HauntedWasteland.Tests/MapTests.cs @@ -39,6 +39,11 @@ public class MapTests MapInput, 2 }, + new object[] + { + File.ReadAllLines("INPUT.txt"), + 13019 + } }; public static IEnumerable ParseMapTestData => From 950922d6e8136c4936cf9577d3db3ec8b9f25d37 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 9 Dec 2023 00:43:17 -0600 Subject: [PATCH 4/6] feat: solve part 2 --- 08/HauntedWasteland.Tests/MapTests.cs | 54 ++++++++++++++- 08/HauntedWasteland/Program.cs | 95 ++++++++++++++++++++++++++- 2 files changed, 143 insertions(+), 6 deletions(-) diff --git a/08/HauntedWasteland.Tests/MapTests.cs b/08/HauntedWasteland.Tests/MapTests.cs index 92462b2..8b307f7 100644 --- a/08/HauntedWasteland.Tests/MapTests.cs +++ b/08/HauntedWasteland.Tests/MapTests.cs @@ -10,12 +10,31 @@ public class MapTests } [Theory] - [MemberData(nameof(TestData.CountTurnsTestData), MemberType = typeof(TestData))] + [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 = @@ -31,7 +50,9 @@ public class MapTests "ZZZ = (ZZZ, ZZZ)", ]; - public static IEnumerable CountTurnsTestData => + private static readonly string[] Input = File.ReadAllLines("INPUT.txt"); + + public static IEnumerable CountStepsTestData => new List { new object[] @@ -41,11 +62,38 @@ public class MapTests }, new object[] { - File.ReadAllLines("INPUT.txt"), + Input, 13019 } }; + public static IEnumerable CountStepsToAllZNodesData => + new List + { + new object[] + { + new string[] + { + "LR", + "", + "11A = (11B, XXX)", + "11B = (XXX, 11Z)", + "11Z = (11B, XXX)", + "22A = (22B, XXX)", + "22B = (22C, 22C)", + "22C = (22Z, 22Z)", + "22Z = (22B, 22B)", + "XXX = (XXX, XXX)", + }, + 6 + }, + new object[] + { + Input, + 13524038372771 + } + }; + public static IEnumerable ParseMapTestData => new List { diff --git a/08/HauntedWasteland/Program.cs b/08/HauntedWasteland/Program.cs index 9f7c8a1..98ce232 100644 --- a/08/HauntedWasteland/Program.cs +++ b/08/HauntedWasteland/Program.cs @@ -18,18 +18,22 @@ public class Program return -2; } + var isPart2 = args.Length > 1 && args[1] == "part2"; var input = await File.ReadAllLinesAsync(args[0]); var stopwatch = new Stopwatch(); stopwatch.Start(); - var result = Map.Parse(input).CountStepsToZ(); + var map = Map.Parse(input); + var result = isPart2 + ? map.CountStepsToAllZNodes() + : map.CountStepsToZ(); stopwatch.Stop(); - Console.WriteLine($"The number of steps to Z is {result}. ({stopwatch.ElapsedMilliseconds}ms)"); + Console.WriteLine($"The number of steps is {result}. ({stopwatch.ElapsedMilliseconds}ms)"); - return result; + return (int)result; } } @@ -70,6 +74,91 @@ public class Map( return steps; } + + // This method finds the prime factors of a given number. + // It takes an integer 'number' as input and returns a list of prime factors. + + public List FindPrimeFactors(long number) + { + var factors = new List(); + + // Start with the smallest prime number, 2. + var divisor = 2; + + // Continue until the number is reduced to 2 or less. + while (number >= 2) + { + // If the number is divisible by the current divisor, + if (number % divisor == 0) + { + // Add the divisor to the list of factors. + factors.Add(divisor); + // Divide the number by the divisor to reduce it. + number /= divisor; + } + else + { + // If the number is not divisible by the current divisor, increment the divisor. + divisor++; + } + } + + return factors; + } + + public long FindLeastCommonMultiple(List numbers) + { + var primeFactors = numbers.Select(FindPrimeFactors).ToList(); + + var uniquePrimeFactors = primeFactors + .SelectMany(pf => pf) + .Distinct() + .ToList(); + + var maxPrimeFactors = uniquePrimeFactors + .Select(upf => primeFactors.Max(pf => pf.Count(f => f == upf))) + .ToList(); + + var result = uniquePrimeFactors + .Zip(maxPrimeFactors) + .Aggregate( + (long)1, + (acc, b) => + // b.First is the prime factor + // b.Second is the number of times it occurs + acc * (long)Math.Pow(b.First, b.Second) + ); + + return result; + } + + public long CountStepsToAllZNodes() + { + var startNodes = Nodes.Where(n => n.Current.EndsWith('A')).ToList(); + var nodeSteps = new List(); + + foreach (var startNode in startNodes) + { + var current = startNode; + var steps = 0; + + while (current.Current.EndsWith('Z') is false) + { + var next = Turns[steps % Turns.Count] switch + { + 'R' => current.Right, + 'L' => current.Left, + _ => throw new Exception("Invalid turn") + }; + current = Nodes.First(n => n.Current == next); + steps++; + } + + nodeSteps.Add(steps); + } + + return FindLeastCommonMultiple(nodeSteps); + } } public class Node( From c5f9c49bea393e2d0d9d492f6950f7e174f0fee1 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 9 Dec 2023 00:47:02 -0600 Subject: [PATCH 5/6] chore: add xml comments --- 08/HauntedWasteland/Program.cs | 65 ++++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 3 deletions(-) diff --git a/08/HauntedWasteland/Program.cs b/08/HauntedWasteland/Program.cs index 98ce232..df08344 100644 --- a/08/HauntedWasteland/Program.cs +++ b/08/HauntedWasteland/Program.cs @@ -37,14 +37,32 @@ public class Program } } +/// +/// A map of the Haunted Wasteland. +/// +/// The turns to take at each step. +/// The nodes in the map. +/// An instance of . public class Map( List turns, List nodes ) { + /// + /// Gets the turns to take at each step. + /// public List Turns { get; init; } = turns; + + /// + /// Gets the nodes in the map. + /// public List Nodes { get; init; } = nodes; + /// + /// Parses a map from a string array. + /// + /// The map input. + /// An instance of . public static Map Parse(string[] mapInput) { var turns = mapInput[0].ToList(); @@ -55,6 +73,10 @@ public class Map( return new Map(turns, nodes); } + /// + /// Counts the number of steps to the Z node. + /// + /// The number of steps to the Z node. public int CountStepsToZ() { var current = Nodes.First(n => n.Current == "AAA"); @@ -75,9 +97,11 @@ public class Map( return steps; } - // This method finds the prime factors of a given number. - // It takes an integer 'number' as input and returns a list of prime factors. - + /// + /// Finds the prime factors of a number. + /// + /// The number to find the prime factors of. + /// The prime factors of the number. public List FindPrimeFactors(long number) { var factors = new List(); @@ -106,6 +130,11 @@ public class Map( return factors; } + /// + /// Finds the least common multiple of a list of numbers. + /// + /// The numbers to find the least common multiple of. + /// The least common multiple of the numbers. public long FindLeastCommonMultiple(List numbers) { var primeFactors = numbers.Select(FindPrimeFactors).ToList(); @@ -132,6 +161,10 @@ public class Map( return result; } + /// + /// Counts the number of steps to all Z nodes. + /// + /// The number of steps to all Z nodes. public long CountStepsToAllZNodes() { var startNodes = Nodes.Where(n => n.Current.EndsWith('A')).ToList(); @@ -161,21 +194,47 @@ public class Map( } } +/// +/// A node in the map. +/// +/// The current node. +/// The left node. +/// The right node. +/// An instance of . public class Node( string current, string left, string right ) { + /// + /// Gets the current node. + /// public string Current { get; init; } = current; + + /// + /// Gets the left node. + /// public string Left { get; init; } = left; + + /// + /// Gets the right node. + /// public string Right { get; init; } = right; + /// + /// Casts the node to a string. + /// public override string ToString() { return $"{Current} = ({Left},{Right})"; } + /// + /// Parses a node from a string. + /// + /// The node string. + /// An instance of . public static Node Parse(string nodeString) { var parts = nodeString.Split( From cb301933d12f43a51f2b84efbc6c96e004d7da7e Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 9 Dec 2023 00:48:26 -0600 Subject: [PATCH 6/6] docs: update README.md --- README.md | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 2deff4e..8fb3106 100644 --- a/README.md +++ b/README.md @@ -42,30 +42,30 @@ dotnet build ## Challenges -| Day | Problem | Solution | Status | Notes | -| --- | -------------------------- | :-----------------------------: | :----: | ------------------------------------------------------------------------------------------------------- | -| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/) | ✅ | The trickiest part here was accounting for overlapping digit words. | -| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/) | ✅ | The key to me here was to parse the input into a useful model. | -| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/GearRatios/) | ✅ | The edge case that got me here was lines ending with a part number. | -| 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/Scratchcards/) | ✅ | Part 2 gets out of hand quickly with just 200 cards. | -| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/IYGASAF/) | ✅ | I brute forced part 2 using parallelism. I know shame. | -| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/WaitForIt/) | ✅ | Thank goodness part 2 was not like 5's part 2. 😅 | -| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/CamelCards/) | ✅ | What took me longest here was I missed a case when jokers are wild and there are three groups of cards. | -| 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/) | ⌛ | -| 09 | [Problem](./09/PROBLEM.md) | [Solution](./09/) | ⌛ | -| 10 | [Problem](./10/PROBLEM.md) | [Solution](./10/) | ⌛ | -| 11 | [Problem](./11/PROBLEM.md) | [Solution](./11/) | ⌛ | -| 12 | [Problem](./12/PROBLEM.md) | [Solution](./12/) | ⌛ | -| 13 | [Problem](./13/PROBLEM.md) | [Solution](./13/) | ⌛ | -| 14 | [Problem](./14/PROBLEM.md) | [Solution](./14/) | ⌛ | -| 15 | [Problem](./15/PROBLEM.md) | [Solution](./15/) | ⌛ | -| 16 | [Problem](./16/PROBLEM.md) | [Solution](./16/) | ⌛ | -| 17 | [Problem](./17/PROBLEM.md) | [Solution](./17/) | ⌛ | -| 18 | [Problem](./18/PROBLEM.md) | [Solution](./18/) | ⌛ | -| 19 | [Problem](./19/PROBLEM.md) | [Solution](./19/) | ⌛ | -| 20 | [Problem](./20/PROBLEM.md) | [Solution](./20/) | ⌛ | -| 21 | [Problem](./21/PROBLEM.md) | [Solution](./21/) | ⌛ | -| 22 | [Problem](./22/PROBLEM.md) | [Solution](./22/) | ⌛ | -| 23 | [Problem](./23/PROBLEM.md) | [Solution](./23/) | ⌛ | -| 24 | [Problem](./24/PROBLEM.md) | [Solution](./24/) | ⌛ | -| 25 | [Problem](./25/PROBLEM.md) | [Solution](./25/) | ⌛ | +| Day | Problem | Solution | Status | Notes | +| --- | -------------------------- | :--------------------------------: | :----: | ------------------------------------------------------------------------------------------------------- | +| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/) | ✅ | The trickiest part here was accounting for overlapping digit words. | +| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/) | ✅ | The key to me here was to parse the input into a useful model. | +| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/GearRatios/) | ✅ | The edge case that got me here was lines ending with a part number. | +| 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/Scratchcards/) | ✅ | Part 2 gets out of hand quickly with just 200 cards. | +| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/IYGASAF/) | ✅ | I brute forced part 2 using parallelism. I know shame. | +| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/WaitForIt/) | ✅ | Thank goodness part 2 was not like 5's part 2. 😅 | +| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/CamelCards/) | ✅ | What took me longest here was I missed a case when jokers are wild and there are three groups of cards. | +| 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/HauntedWasteland/) | ✅ | Got to implement a least common multiple algorithm for part 2. | +| 09 | [Problem](./09/PROBLEM.md) | [Solution](./09/) | ⌛ | +| 10 | [Problem](./10/PROBLEM.md) | [Solution](./10/) | ⌛ | +| 11 | [Problem](./11/PROBLEM.md) | [Solution](./11/) | ⌛ | +| 12 | [Problem](./12/PROBLEM.md) | [Solution](./12/) | ⌛ | +| 13 | [Problem](./13/PROBLEM.md) | [Solution](./13/) | ⌛ | +| 14 | [Problem](./14/PROBLEM.md) | [Solution](./14/) | ⌛ | +| 15 | [Problem](./15/PROBLEM.md) | [Solution](./15/) | ⌛ | +| 16 | [Problem](./16/PROBLEM.md) | [Solution](./16/) | ⌛ | +| 17 | [Problem](./17/PROBLEM.md) | [Solution](./17/) | ⌛ | +| 18 | [Problem](./18/PROBLEM.md) | [Solution](./18/) | ⌛ | +| 19 | [Problem](./19/PROBLEM.md) | [Solution](./19/) | ⌛ | +| 20 | [Problem](./20/PROBLEM.md) | [Solution](./20/) | ⌛ | +| 21 | [Problem](./21/PROBLEM.md) | [Solution](./21/) | ⌛ | +| 22 | [Problem](./22/PROBLEM.md) | [Solution](./22/) | ⌛ | +| 23 | [Problem](./23/PROBLEM.md) | [Solution](./23/) | ⌛ | +| 24 | [Problem](./24/PROBLEM.md) | [Solution](./24/) | ⌛ | +| 25 | [Problem](./25/PROBLEM.md) | [Solution](./25/) | ⌛ |