From 3d820e46520c8fe4abbf389ea2a12e226590e4da Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 2 Dec 2023 09:31:45 -0600 Subject: [PATCH 1/7] chore: scaffold for day 2 puzzle --- .../CubeConundrum.Tests.csproj | 30 +++++++++++++++++++ 02/CubeConundrum.Tests/GlobalUsings.cs | 1 + 02/CubeConundrum.Tests/UnitTest1.cs | 10 +++++++ 02/CubeConundrum/CubeConundrum.csproj | 10 +++++++ 02/CubeConundrum/Program.cs | 2 ++ AdventOfCode2023.sln | 16 ++++++++++ 6 files changed, 69 insertions(+) create mode 100644 02/CubeConundrum.Tests/CubeConundrum.Tests.csproj create mode 100644 02/CubeConundrum.Tests/GlobalUsings.cs create mode 100644 02/CubeConundrum.Tests/UnitTest1.cs create mode 100644 02/CubeConundrum/CubeConundrum.csproj create mode 100644 02/CubeConundrum/Program.cs diff --git a/02/CubeConundrum.Tests/CubeConundrum.Tests.csproj b/02/CubeConundrum.Tests/CubeConundrum.Tests.csproj new file mode 100644 index 0000000..2346b86 --- /dev/null +++ b/02/CubeConundrum.Tests/CubeConundrum.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/02/CubeConundrum.Tests/GlobalUsings.cs b/02/CubeConundrum.Tests/GlobalUsings.cs new file mode 100644 index 0000000..8c927eb --- /dev/null +++ b/02/CubeConundrum.Tests/GlobalUsings.cs @@ -0,0 +1 @@ +global using Xunit; \ No newline at end of file diff --git a/02/CubeConundrum.Tests/UnitTest1.cs b/02/CubeConundrum.Tests/UnitTest1.cs new file mode 100644 index 0000000..d26506e --- /dev/null +++ b/02/CubeConundrum.Tests/UnitTest1.cs @@ -0,0 +1,10 @@ +namespace CubeConundrum.Tests; + +public class UnitTest1 +{ + [Fact] + public void Test1() + { + + } +} \ No newline at end of file diff --git a/02/CubeConundrum/CubeConundrum.csproj b/02/CubeConundrum/CubeConundrum.csproj new file mode 100644 index 0000000..2150e37 --- /dev/null +++ b/02/CubeConundrum/CubeConundrum.csproj @@ -0,0 +1,10 @@ + + + + Exe + net8.0 + enable + enable + + + diff --git a/02/CubeConundrum/Program.cs b/02/CubeConundrum/Program.cs new file mode 100644 index 0000000..3751555 --- /dev/null +++ b/02/CubeConundrum/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 f97fe91..f685422 100644 --- a/AdventOfCode2023.sln +++ b/AdventOfCode2023.sln @@ -9,6 +9,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Trebuchet", "01\Trebuchet\T EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Trebuchet.Tests", "01\Trebuchet.Tests\Trebuchet.Tests.csproj", "{4A5226E4-5B90-4D6C-9224-EBE3F04470ED}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "02", "02", "{4FD81B09-302F-4C76-BECB-B4559DF3984F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CubeConundrum", "02\CubeConundrum\CubeConundrum.csproj", "{95D6522F-4893-4A66-9B39-7F0268E290B8}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CubeConundrum.Tests", "02\CubeConundrum.Tests\CubeConundrum.Tests.csproj", "{4825CE42-4717-4DA6-944F-9BD9A825932B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -26,9 +32,19 @@ Global {4A5226E4-5B90-4D6C-9224-EBE3F04470ED}.Debug|Any CPU.Build.0 = Debug|Any CPU {4A5226E4-5B90-4D6C-9224-EBE3F04470ED}.Release|Any CPU.ActiveCfg = Release|Any CPU {4A5226E4-5B90-4D6C-9224-EBE3F04470ED}.Release|Any CPU.Build.0 = Release|Any CPU + {95D6522F-4893-4A66-9B39-7F0268E290B8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {95D6522F-4893-4A66-9B39-7F0268E290B8}.Debug|Any CPU.Build.0 = Debug|Any CPU + {95D6522F-4893-4A66-9B39-7F0268E290B8}.Release|Any CPU.ActiveCfg = Release|Any CPU + {95D6522F-4893-4A66-9B39-7F0268E290B8}.Release|Any CPU.Build.0 = Release|Any CPU + {4825CE42-4717-4DA6-944F-9BD9A825932B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4825CE42-4717-4DA6-944F-9BD9A825932B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4825CE42-4717-4DA6-944F-9BD9A825932B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4825CE42-4717-4DA6-944F-9BD9A825932B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {3F8EAC09-4BC7-43AA-B72B-48DDD2710F6D} = {8C29858C-623A-461A-BF0B-254E151CD9C2} {4A5226E4-5B90-4D6C-9224-EBE3F04470ED} = {8C29858C-623A-461A-BF0B-254E151CD9C2} + {95D6522F-4893-4A66-9B39-7F0268E290B8} = {4FD81B09-302F-4C76-BECB-B4559DF3984F} + {4825CE42-4717-4DA6-944F-9BD9A825932B} = {4FD81B09-302F-4C76-BECB-B4559DF3984F} EndGlobalSection EndGlobal From 8cc9c4b3225aa134a7e1d5d95021be93578b77b4 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 2 Dec 2023 09:32:24 -0600 Subject: [PATCH 2/7] docs: update README.md --- README.md | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index d66662c..8ee50d1 100644 --- a/README.md +++ b/README.md @@ -4,30 +4,30 @@ This repository contains my solutions for the [Advent of Code 2023](https://adve ## Challenges -| Day | Problem | Solution | Status | Notes | -| --- | -------------------------- | :-----------------------------------: | :----------------------: | ------------------------------------------------------------------- | -| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/Program.cs) | :white_check_mark: | The trickiest part here was accounting for overlapping digit words. | -| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/) | :hourglass_flowing_sand: | -| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/) | :hourglass_flowing_sand: | -| 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/) | :hourglass_flowing_sand: | -| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/) | :hourglass_flowing_sand: | -| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/) | :hourglass_flowing_sand: | -| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/) | :hourglass_flowing_sand: | -| 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/) | :hourglass_flowing_sand: | -| 09 | [Problem](./09/PROBLEM.md) | [Solution](./09/) | :hourglass_flowing_sand: | -| 10 | [Problem](./10/PROBLEM.md) | [Solution](./10/) | :hourglass_flowing_sand: | -| 11 | [Problem](./11/PROBLEM.md) | [Solution](./11/) | :hourglass_flowing_sand: | -| 12 | [Problem](./12/PROBLEM.md) | [Solution](./12/) | :hourglass_flowing_sand: | -| 13 | [Problem](./13/PROBLEM.md) | [Solution](./13/) | :hourglass_flowing_sand: | -| 14 | [Problem](./14/PROBLEM.md) | [Solution](./14/) | :hourglass_flowing_sand: | -| 15 | [Problem](./15/PROBLEM.md) | [Solution](./15/) | :hourglass_flowing_sand: | -| 16 | [Problem](./16/PROBLEM.md) | [Solution](./16/) | :hourglass_flowing_sand: | -| 17 | [Problem](./17/PROBLEM.md) | [Solution](./17/) | :hourglass_flowing_sand: | -| 18 | [Problem](./18/PROBLEM.md) | [Solution](./18/) | :hourglass_flowing_sand: | -| 19 | [Problem](./19/PROBLEM.md) | [Solution](./19/) | :hourglass_flowing_sand: | -| 20 | [Problem](./20/PROBLEM.md) | [Solution](./20/) | :hourglass_flowing_sand: | -| 21 | [Problem](./21/PROBLEM.md) | [Solution](./21/) | :hourglass_flowing_sand: | -| 22 | [Problem](./22/PROBLEM.md) | [Solution](./22/) | :hourglass_flowing_sand: | -| 23 | [Problem](./23/PROBLEM.md) | [Solution](./23/) | :hourglass_flowing_sand: | -| 24 | [Problem](./24/PROBLEM.md) | [Solution](./24/) | :hourglass_flowing_sand: | -| 25 | [Problem](./25/PROBLEM.md) | [Solution](./25/) | :hourglass_flowing_sand: | +| Day | Problem | Solution | Status | Notes | +| --- | -------------------------- | :---------------------------------------: | :----------------------: | ------------------------------------------------------------------- | +| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/Program.cs) | :white_check_mark: | The trickiest part here was accounting for overlapping digit words. | +| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/Program.cs) | :hourglass_flowing_sand: | +| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/) | :hourglass_flowing_sand: | +| 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/) | :hourglass_flowing_sand: | +| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/) | :hourglass_flowing_sand: | +| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/) | :hourglass_flowing_sand: | +| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/) | :hourglass_flowing_sand: | +| 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/) | :hourglass_flowing_sand: | +| 09 | [Problem](./09/PROBLEM.md) | [Solution](./09/) | :hourglass_flowing_sand: | +| 10 | [Problem](./10/PROBLEM.md) | [Solution](./10/) | :hourglass_flowing_sand: | +| 11 | [Problem](./11/PROBLEM.md) | [Solution](./11/) | :hourglass_flowing_sand: | +| 12 | [Problem](./12/PROBLEM.md) | [Solution](./12/) | :hourglass_flowing_sand: | +| 13 | [Problem](./13/PROBLEM.md) | [Solution](./13/) | :hourglass_flowing_sand: | +| 14 | [Problem](./14/PROBLEM.md) | [Solution](./14/) | :hourglass_flowing_sand: | +| 15 | [Problem](./15/PROBLEM.md) | [Solution](./15/) | :hourglass_flowing_sand: | +| 16 | [Problem](./16/PROBLEM.md) | [Solution](./16/) | :hourglass_flowing_sand: | +| 17 | [Problem](./17/PROBLEM.md) | [Solution](./17/) | :hourglass_flowing_sand: | +| 18 | [Problem](./18/PROBLEM.md) | [Solution](./18/) | :hourglass_flowing_sand: | +| 19 | [Problem](./19/PROBLEM.md) | [Solution](./19/) | :hourglass_flowing_sand: | +| 20 | [Problem](./20/PROBLEM.md) | [Solution](./20/) | :hourglass_flowing_sand: | +| 21 | [Problem](./21/PROBLEM.md) | [Solution](./21/) | :hourglass_flowing_sand: | +| 22 | [Problem](./22/PROBLEM.md) | [Solution](./22/) | :hourglass_flowing_sand: | +| 23 | [Problem](./23/PROBLEM.md) | [Solution](./23/) | :hourglass_flowing_sand: | +| 24 | [Problem](./24/PROBLEM.md) | [Solution](./24/) | :hourglass_flowing_sand: | +| 25 | [Problem](./25/PROBLEM.md) | [Solution](./25/) | :hourglass_flowing_sand: | From dc8bd473b99c9f32c8bb1019b6e24495eda461d8 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 2 Dec 2023 10:41:00 -0600 Subject: [PATCH 3/7] feat: create parser to parse game into model --- .../PartTwoPuzzleSolverTests.cs | 2 +- 02/CubeConundrum.Tests/GlobalUsings.cs | 3 +- 02/CubeConundrum.Tests/PuzzleParserTests.cs | 94 +++++++++++++++++++ 02/CubeConundrum.Tests/UnitTest1.cs | 10 -- 02/CubeConundrum/Program.cs | 87 ++++++++++++++++- 02/SCRATCH.md | 75 +++++++++++++++ README.md | 54 +++++------ 7 files changed, 284 insertions(+), 41 deletions(-) create mode 100644 02/CubeConundrum.Tests/PuzzleParserTests.cs delete mode 100644 02/CubeConundrum.Tests/UnitTest1.cs create mode 100644 02/SCRATCH.md diff --git a/01/Trebuchet.Tests/PartTwoPuzzleSolverTests.cs b/01/Trebuchet.Tests/PartTwoPuzzleSolverTests.cs index 3854d4f..3e7cd26 100644 --- a/01/Trebuchet.Tests/PartTwoPuzzleSolverTests.cs +++ b/01/Trebuchet.Tests/PartTwoPuzzleSolverTests.cs @@ -36,6 +36,6 @@ public class PartTwoPuzzleSolverTests { var input = await File.ReadAllLinesAsync("INPUT.txt"); var result = _sut.SumCalibrationValues(input); - result.Should().BeLessThan(54249); + result.Should().Be(54249); } } \ No newline at end of file diff --git a/02/CubeConundrum.Tests/GlobalUsings.cs b/02/CubeConundrum.Tests/GlobalUsings.cs index 8c927eb..7fef4b0 100644 --- a/02/CubeConundrum.Tests/GlobalUsings.cs +++ b/02/CubeConundrum.Tests/GlobalUsings.cs @@ -1 +1,2 @@ -global using Xunit; \ No newline at end of file +global using Xunit; +global using FluentAssertions; \ No newline at end of file diff --git a/02/CubeConundrum.Tests/PuzzleParserTests.cs b/02/CubeConundrum.Tests/PuzzleParserTests.cs new file mode 100644 index 0000000..22bdd05 --- /dev/null +++ b/02/CubeConundrum.Tests/PuzzleParserTests.cs @@ -0,0 +1,94 @@ +namespace CubeConundrum.Tests; + +public class PuzzleParserTests +{ + private readonly PuzzleParser _sut = new(); + + [Theory, MemberData(nameof(TestData.CubeStrings), MemberType = typeof(TestData))] + public void ParseCube_GivenAStringThatRepresentsACube_ItShouldReturnTheEquivalentCubeModel(string input, Cube expected) + { + var result = _sut.ParseCube(input); + result.Should().BeEquivalentTo(expected); + } + + [Theory, MemberData(nameof(TestData.ResultStrings), MemberType = typeof(TestData))] + public void ParseResult_GivenAStringThatRepresentsAResult_ItShouldReturnTheEquivalentResultModel(string input, Result expected) + { + var result = _sut.ParseResult(input); + result.Should().BeEquivalentTo(expected); + } + + [Theory, MemberData(nameof(TestData.GameStrings), MemberType = typeof(TestData))] + public void ParseGame_GivenAStringThatRepresentsAGame_ItShouldReturnTheEquivalentGameModel(string input, Game expected) + { + var result = _sut.ParseGame(input); + result.Should().BeEquivalentTo(expected); + } +} + +public static class TestData +{ + public static readonly IEnumerable CubeStrings = new List + { + new object[] { "4 red", new Cube { Count = 4, Color = CubeColor.Red } }, + new object[] { "1 green", new Cube { Count = 1, Color = CubeColor.Green } }, + new object[] { "2 blue", new Cube { Count = 2, Color = CubeColor.Blue } } + }; + + public static readonly IEnumerable ResultStrings = new List + { + new object[] + { + "4 red, 1 green, 2 blue", + new Result + { + Cubes = + [ + new (){ Count = 4, Color = CubeColor.Red }, + new (){ Count = 1, Color = CubeColor.Green }, + new() { Count = 2, Color = CubeColor.Blue } + ] + } + } + }; + + public static readonly IEnumerable GameStrings = new List + { + new object[] + { + "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green", + new Game + { + Id = 1, + Results = + [ + new() + { + Cubes = + [ + new() { Count = 3, Color = CubeColor.Blue }, + new() { Count = 4, Color = CubeColor.Red } + ] + }, + new Result + { + Cubes = + [ + new() { Count = 1, Color = CubeColor.Red }, + new() { Count = 2, Color = CubeColor.Green }, + new() { Count = 6, Color = CubeColor.Blue } + ] + }, + new Result + { + Cubes = + [ + new(){ Count = 2, Color = CubeColor.Green } + ] + } + ] + } + } + }; + +} \ No newline at end of file diff --git a/02/CubeConundrum.Tests/UnitTest1.cs b/02/CubeConundrum.Tests/UnitTest1.cs deleted file mode 100644 index d26506e..0000000 --- a/02/CubeConundrum.Tests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace CubeConundrum.Tests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - - } -} \ No newline at end of file diff --git a/02/CubeConundrum/Program.cs b/02/CubeConundrum/Program.cs index 3751555..f71439b 100644 --- a/02/CubeConundrum/Program.cs +++ b/02/CubeConundrum/Program.cs @@ -1,2 +1,85 @@ -// See https://aka.ms/new-console-template for more information -Console.WriteLine("Hello, World!"); +namespace CubeConundrum; + +public class Program +{ + public async static Task Main(string[] args) + { + return await Task.FromResult(0); + } +} + +public class PartOnePuzzleSolver +{ + +} + +public class PuzzleParser +{ + public Cube ParseCube(string cubeString) + { + var parts = cubeString.Split(' '); + var count = int.Parse(parts[0]); + var color = Enum.Parse(parts[1], true); + + return new() + { + Count = count, + Color = color + }; + } + + public Result ParseResult(string resultString) + { + var cubes = resultString + .Split(',') + .Select(s => s.Trim()) + .Select(ParseCube) + .ToList(); + + return new() + { + Cubes = cubes + }; + } + + public Game ParseGame(string gameString) + { + var parts = gameString.Split(':'); + var gameId = int.Parse(parts[0].Split(' ')[1]); + var results = parts[1] + .Split(';') + .Select(s => s.Trim()) + .Select(ParseResult) + .ToList(); + + return new() + { + Id = gameId, + Results = results + }; + } +} + +public class Game +{ + public int Id { get; set; } + public List Results { get; set; } = []; +} + +public class Result +{ + public List Cubes { get; set; } = []; +} + +public class Cube +{ + public int Count { get; set; } + public CubeColor Color { get; set; } +} + +public enum CubeColor +{ + Red, + Green, + Blue +} \ No newline at end of file diff --git a/02/SCRATCH.md b/02/SCRATCH.md new file mode 100644 index 0000000..8a7389e --- /dev/null +++ b/02/SCRATCH.md @@ -0,0 +1,75 @@ +# Notes + +## Constraints + +### Total number of cubes: 39 + +The elf can't show me more than 39 dice at a time. + +### Total number of each cube type: 12 red, 13 green, 14 blue + +The elf can't show me more than 12 red cubes at a time. +The elf can't show me more than 13 green cubes at a time. +The elf can't show me more than 14 blue cubes at a time. + +### Types of cubes: red, green, blue + +The elf can only show me red, green, or blue cubes. +The elf though can show me any combination of red, green, or blue cubes including none of a particular color or all of a particular color. + +## Structure + +Each game is a line of text. +Each game is delimited by "Game N: " where N is the game id. +Each game consists of a semi-colon delimited list of sets of cubes. +Each set of cubes is a comma delimited list of the number of cubes and the color of the cubes. + +```text +Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green +``` + +❓ How would I model this? + +```csharp +class Game +{ + public int Id { get; set; } + public List Results { get; set; } +} + +class Results +{ + public List Cubes { get; set; } +} + +class Cube +{ + public int Count { get; set; } + public CubeColor Color { get; set; } +} + +enum CubeColor +{ + Red, + Green, + Blue +} +``` + +## Problems + +### Problem 1 + +🔴 Need to determine which results are possible given the known # of cubes and known # of cubes for each color. + +### Problem 2 + +🔴 Need to determine if all the results for a given game are possible + +### Problem 3 + +🔴 Need to determine the sum of the game ids for all the possible games + +### Problem 4 + +🔴 Need to determine the sum of the game ids for all the possible games diff --git a/README.md b/README.md index 8ee50d1..dac8b30 100644 --- a/README.md +++ b/README.md @@ -4,30 +4,30 @@ This repository contains my solutions for the [Advent of Code 2023](https://adve ## Challenges -| Day | Problem | Solution | Status | Notes | -| --- | -------------------------- | :---------------------------------------: | :----------------------: | ------------------------------------------------------------------- | -| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/Program.cs) | :white_check_mark: | The trickiest part here was accounting for overlapping digit words. | -| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/Program.cs) | :hourglass_flowing_sand: | -| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/) | :hourglass_flowing_sand: | -| 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/) | :hourglass_flowing_sand: | -| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/) | :hourglass_flowing_sand: | -| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/) | :hourglass_flowing_sand: | -| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/) | :hourglass_flowing_sand: | -| 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/) | :hourglass_flowing_sand: | -| 09 | [Problem](./09/PROBLEM.md) | [Solution](./09/) | :hourglass_flowing_sand: | -| 10 | [Problem](./10/PROBLEM.md) | [Solution](./10/) | :hourglass_flowing_sand: | -| 11 | [Problem](./11/PROBLEM.md) | [Solution](./11/) | :hourglass_flowing_sand: | -| 12 | [Problem](./12/PROBLEM.md) | [Solution](./12/) | :hourglass_flowing_sand: | -| 13 | [Problem](./13/PROBLEM.md) | [Solution](./13/) | :hourglass_flowing_sand: | -| 14 | [Problem](./14/PROBLEM.md) | [Solution](./14/) | :hourglass_flowing_sand: | -| 15 | [Problem](./15/PROBLEM.md) | [Solution](./15/) | :hourglass_flowing_sand: | -| 16 | [Problem](./16/PROBLEM.md) | [Solution](./16/) | :hourglass_flowing_sand: | -| 17 | [Problem](./17/PROBLEM.md) | [Solution](./17/) | :hourglass_flowing_sand: | -| 18 | [Problem](./18/PROBLEM.md) | [Solution](./18/) | :hourglass_flowing_sand: | -| 19 | [Problem](./19/PROBLEM.md) | [Solution](./19/) | :hourglass_flowing_sand: | -| 20 | [Problem](./20/PROBLEM.md) | [Solution](./20/) | :hourglass_flowing_sand: | -| 21 | [Problem](./21/PROBLEM.md) | [Solution](./21/) | :hourglass_flowing_sand: | -| 22 | [Problem](./22/PROBLEM.md) | [Solution](./22/) | :hourglass_flowing_sand: | -| 23 | [Problem](./23/PROBLEM.md) | [Solution](./23/) | :hourglass_flowing_sand: | -| 24 | [Problem](./24/PROBLEM.md) | [Solution](./24/) | :hourglass_flowing_sand: | -| 25 | [Problem](./25/PROBLEM.md) | [Solution](./25/) | :hourglass_flowing_sand: | +| Day | Problem | Solution | Status | Notes | +| --- | -------------------------- | :---------------------------------------: | :----: | ------------------------------------------------------------------- | +| 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/Program.cs) | ✅ | The trickiest part here was accounting for overlapping digit words. | +| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/Program.cs) | ⌛ | +| 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/) | ⌛ | +| 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/) | ⌛ | +| 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/) | ⌛ | +| 06 | [Problem](./06/PROBLEM.md) | [Solution](./06/) | ⌛ | +| 07 | [Problem](./07/PROBLEM.md) | [Solution](./07/) | ⌛ | +| 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/) | ⌛ | From 9059ea7b9fbab827472f40f56deb8c116dfcc146 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 2 Dec 2023 11:05:34 -0600 Subject: [PATCH 4/7] feat: add logic for testing game possibility and summing possible games --- 01/Trebuchet.Tests/GlobalUsings.cs | 3 +- 02/CubeConundrum.Tests/GlobalUsings.cs | 3 +- .../PartOnePuzzleSolverTests.cs | 159 ++++++++++++++++++ 02/CubeConundrum.Tests/PuzzleParserTests.cs | 117 +++++++------ 02/CubeConundrum.Tests/ResultTests.cs | 23 +++ 02/CubeConundrum/Program.cs | 18 ++ 6 files changed, 262 insertions(+), 61 deletions(-) create mode 100644 02/CubeConundrum.Tests/PartOnePuzzleSolverTests.cs create mode 100644 02/CubeConundrum.Tests/ResultTests.cs diff --git a/01/Trebuchet.Tests/GlobalUsings.cs b/01/Trebuchet.Tests/GlobalUsings.cs index 7fef4b0..2d5b473 100644 --- a/01/Trebuchet.Tests/GlobalUsings.cs +++ b/01/Trebuchet.Tests/GlobalUsings.cs @@ -1,2 +1,3 @@ +global using FluentAssertions; + global using Xunit; -global using FluentAssertions; \ No newline at end of file diff --git a/02/CubeConundrum.Tests/GlobalUsings.cs b/02/CubeConundrum.Tests/GlobalUsings.cs index 7fef4b0..2d5b473 100644 --- a/02/CubeConundrum.Tests/GlobalUsings.cs +++ b/02/CubeConundrum.Tests/GlobalUsings.cs @@ -1,2 +1,3 @@ +global using FluentAssertions; + global using Xunit; -global using FluentAssertions; \ No newline at end of file diff --git a/02/CubeConundrum.Tests/PartOnePuzzleSolverTests.cs b/02/CubeConundrum.Tests/PartOnePuzzleSolverTests.cs new file mode 100644 index 0000000..ba7acaa --- /dev/null +++ b/02/CubeConundrum.Tests/PartOnePuzzleSolverTests.cs @@ -0,0 +1,159 @@ +namespace CubeConundrum.Tests; + +public class PartOnePuzzleSolverTests +{ + private readonly PartOnePuzzleSolver _sut = new(); + + [Theory, MemberData(nameof(TestData.Results), MemberType = typeof(TestData))] + public void IsResultPossible_GivenAResult_ItShouldReturnExpectedOutcome(Result givenResult, bool expected) + { + var result = _sut.IsResultPossible(givenResult); + result.Should().Be(expected); + } + + [Theory, MemberData(nameof(TestData.Games), MemberType = typeof(TestData))] + public void IsGamePossible_GivenAGame_ItShouldReturnExpectedOutcome(Game givenGame, bool expected) + { + var result = _sut.IsGamePossible(givenGame); + result.Should().Be(expected); + } + + [Fact] + public void SumPossibleGameIds_GivenAGameCollection_ItShouldReturnTheSumOfTheIdsOfAllPossibleGames() + { + var games = TestData.Games.Select(o => (Game)o[0]); + var result = _sut.SumPossibleGameIds(games); + result.Should().Be(1); + } + + public static class TestData + { + public static readonly IEnumerable Games = new List + { + new object[] + { + new Game + { + Id = 1, + Results = + { + new() + { + Cubes = + { + new() { Count = 3, Color = CubeColor.Blue }, + new() { Count = 4, Color = CubeColor.Red } + } + }, + new() + { + Cubes = + { + new() { Count = 1, Color = CubeColor.Red }, + new() { Count = 2, Color = CubeColor.Green }, + new() { Count = 6, Color = CubeColor.Blue } + } + }, + new() + { + Cubes = + { + new() { Count = 2, Color = CubeColor.Green } + } + } + } + }, + true + }, + new object[] + { + new Game + { + Id = 2, + Results = + { + new() + { + Cubes = + { + new() { Count = 3, Color = CubeColor.Blue }, + new() { Count = 4, Color = CubeColor.Red } + } + }, + new() + { + Cubes = + { + new() { Count = 1, Color = CubeColor.Red }, + new() { Count = 2, Color = CubeColor.Green }, + new() { Count = 6, Color = CubeColor.Blue } + } + }, + new() + { + Cubes = + { + new() { Count = 40, Color = CubeColor.Green } + } + }, + } + }, + false + }, + }; + + public static readonly IEnumerable Results = new List + { + new object[] + { + new Result + { + Cubes = + { + new() { Count = 4, Color = CubeColor.Red }, + new() { Count = 1, Color = CubeColor.Green }, + new() { Count = 2, Color = CubeColor.Blue } + } + }, + true + }, + new object[] + { + new Result + { + Cubes = + { + new() { Count = 13, Color = CubeColor.Red }, + new() { Count = 14, Color = CubeColor.Green }, + new() { Count = 14, Color = CubeColor.Blue }, + } + }, + false + }, + new object[] + { + new Result + { + Cubes = + { + new() { Count = 13, Color = CubeColor.Red }, + new() { Count = 5, Color = CubeColor.Green }, + new() { Count = 5, Color = CubeColor.Blue }, + } + }, + false + }, + new object[] + { + new Result + { + Cubes = + { + new() { Count = 40, Color = CubeColor.Red }, + } + }, + false + } + }; + } +} \ No newline at end of file diff --git a/02/CubeConundrum.Tests/PuzzleParserTests.cs b/02/CubeConundrum.Tests/PuzzleParserTests.cs index 22bdd05..5ac4fa8 100644 --- a/02/CubeConundrum.Tests/PuzzleParserTests.cs +++ b/02/CubeConundrum.Tests/PuzzleParserTests.cs @@ -24,71 +24,70 @@ public class PuzzleParserTests var result = _sut.ParseGame(input); result.Should().BeEquivalentTo(expected); } -} -public static class TestData -{ - public static readonly IEnumerable CubeStrings = new List + public static class TestData { - new object[] { "4 red", new Cube { Count = 4, Color = CubeColor.Red } }, - new object[] { "1 green", new Cube { Count = 1, Color = CubeColor.Green } }, - new object[] { "2 blue", new Cube { Count = 2, Color = CubeColor.Blue } } - }; - - public static readonly IEnumerable ResultStrings = new List - { - new object[] + public static readonly IEnumerable CubeStrings = new List { - "4 red, 1 green, 2 blue", - new Result - { - Cubes = - [ - new (){ Count = 4, Color = CubeColor.Red }, - new (){ Count = 1, Color = CubeColor.Green }, - new() { Count = 2, Color = CubeColor.Blue } - ] - } - } - }; + new object[] { "4 red", new Cube { Count = 4, Color = CubeColor.Red } }, + new object[] { "1 green", new Cube { Count = 1, Color = CubeColor.Green } }, + new object[] { "2 blue", new Cube { Count = 2, Color = CubeColor.Blue } } + }; - public static readonly IEnumerable GameStrings = new List - { - new object[] + public static readonly IEnumerable ResultStrings = new List { - "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green", - new Game + new object[] { - Id = 1, - Results = - [ - new() - { - Cubes = - [ - new() { Count = 3, Color = CubeColor.Blue }, - new() { Count = 4, Color = CubeColor.Red } - ] - }, - new Result - { - Cubes = - [ - new() { Count = 1, Color = CubeColor.Red }, - new() { Count = 2, Color = CubeColor.Green }, - new() { Count = 6, Color = CubeColor.Blue } - ] - }, - new Result - { - Cubes = - [ - new(){ Count = 2, Color = CubeColor.Green } - ] - } - ] + "4 red, 1 green, 2 blue", + new Result + { + Cubes = + [ + new (){ Count = 4, Color = CubeColor.Red }, + new (){ Count = 1, Color = CubeColor.Green }, + new() { Count = 2, Color = CubeColor.Blue } + ] + } } - } - }; + }; + public static readonly IEnumerable GameStrings = new List + { + new object[] + { + "Game 1: 3 blue, 4 red; 1 red, 2 green, 6 blue; 2 green", + new Game + { + Id = 1, + Results = + [ + new() + { + Cubes = + [ + new() { Count = 3, Color = CubeColor.Blue }, + new() { Count = 4, Color = CubeColor.Red } + ] + }, + new Result + { + Cubes = + [ + new() { Count = 1, Color = CubeColor.Red }, + new() { Count = 2, Color = CubeColor.Green }, + new() { Count = 6, Color = CubeColor.Blue } + ] + }, + new Result + { + Cubes = + [ + new(){ Count = 2, Color = CubeColor.Green } + ] + } + ] + } + } + }; + } } \ No newline at end of file diff --git a/02/CubeConundrum.Tests/ResultTests.cs b/02/CubeConundrum.Tests/ResultTests.cs new file mode 100644 index 0000000..4aad52b --- /dev/null +++ b/02/CubeConundrum.Tests/ResultTests.cs @@ -0,0 +1,23 @@ +namespace CubeConundrum.Tests; + +public class ResultTests +{ + [Fact] + public void CountProperties_GivenAResult_ItShouldReturnTheCorrectCount() + { + var result = new Result + { + Cubes = + { + new() { Count = 4, Color = CubeColor.Red }, + new() { Count = 1, Color = CubeColor.Green }, + new() { Count = 2, Color = CubeColor.Blue } + } + }; + + result.TotalCubeCount.Should().Be(7); + result.RedCubeCount.Should().Be(4); + result.GreenCubeCount.Should().Be(1); + result.BlueCubeCount.Should().Be(2); + } +} \ No newline at end of file diff --git a/02/CubeConundrum/Program.cs b/02/CubeConundrum/Program.cs index f71439b..4b32802 100644 --- a/02/CubeConundrum/Program.cs +++ b/02/CubeConundrum/Program.cs @@ -10,7 +10,21 @@ public class Program public class PartOnePuzzleSolver { + private readonly int _maxCubeCount = 39; + private readonly int _maxRedCubeCount = 12; + private readonly int _maxGreenCubeCount = 13; + private readonly int _maxBlueCubeCount = 14; + public bool IsResultPossible(Result result) => result.TotalCubeCount <= _maxCubeCount + && result.RedCubeCount <= _maxRedCubeCount + && result.GreenCubeCount <= _maxGreenCubeCount + && result.BlueCubeCount <= _maxBlueCubeCount; + + public bool IsGamePossible(Game game) => game.Results.All(IsResultPossible); + + public int SumPossibleGameIds(IEnumerable games) => games + .Where(IsGamePossible) + .Sum(g => g.Id); } public class PuzzleParser @@ -69,6 +83,10 @@ public class Game public class Result { public List Cubes { get; set; } = []; + public int TotalCubeCount => Cubes.Sum(c => c.Count); + public int RedCubeCount => Cubes.Where(c => c.Color == CubeColor.Red).Sum(c => c.Count); + public int GreenCubeCount => Cubes.Where(c => c.Color == CubeColor.Green).Sum(c => c.Count); + public int BlueCubeCount => Cubes.Where(c => c.Color == CubeColor.Blue).Sum(c => c.Count); } public class Cube From ea65c5d830ce3384057bc6f2f7f33ef4672a39dd Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 2 Dec 2023 11:12:26 -0600 Subject: [PATCH 5/7] feat: solved part 1 --- .../CubeConundrum.Tests.csproj | 6 +++++ 02/CubeConundrum.Tests/ProgramTests.cs | 11 +++++++++ 02/CubeConundrum/Program.cs | 23 ++++++++++++++++++- 3 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 02/CubeConundrum.Tests/ProgramTests.cs diff --git a/02/CubeConundrum.Tests/CubeConundrum.Tests.csproj b/02/CubeConundrum.Tests/CubeConundrum.Tests.csproj index 2346b86..26a27fd 100644 --- a/02/CubeConundrum.Tests/CubeConundrum.Tests.csproj +++ b/02/CubeConundrum.Tests/CubeConundrum.Tests.csproj @@ -27,4 +27,10 @@ + + + PreserveNewest + + + diff --git a/02/CubeConundrum.Tests/ProgramTests.cs b/02/CubeConundrum.Tests/ProgramTests.cs new file mode 100644 index 0000000..5148b3d --- /dev/null +++ b/02/CubeConundrum.Tests/ProgramTests.cs @@ -0,0 +1,11 @@ +namespace CubeConundrum.Tests; + +public class ProgramTests +{ + [Fact] + public async Task Main_GivenInput_ItShouldReturnExpectedSum() + { + var result = await Program.Main(["INPUT.txt"]); + result.Should().Be(2879); + } +} \ No newline at end of file diff --git a/02/CubeConundrum/Program.cs b/02/CubeConundrum/Program.cs index 4b32802..b1d5b08 100644 --- a/02/CubeConundrum/Program.cs +++ b/02/CubeConundrum/Program.cs @@ -4,7 +4,28 @@ public class Program { public async static Task Main(string[] args) { - return await Task.FromResult(0); + 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 puzzleParser = new PuzzleParser(); + var puzzleSolver = new PartOnePuzzleSolver(); + + var input = await File.ReadAllLinesAsync(args[0]); + var games = input.Select(puzzleParser.ParseGame); + var result = puzzleSolver.SumPossibleGameIds(games); + + Console.WriteLine($"The sum of all possible game ids is {result}."); + + return result; } } From f99414041cdf4019892832dea5da69368b7b2826 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 2 Dec 2023 12:46:56 -0600 Subject: [PATCH 6/7] chore: add xml comments --- 02/CubeConundrum.Tests/GameTests.cs | 52 +++++++ 02/CubeConundrum.Tests/ProgramTests.cs | 7 + ...zleSolverTests.cs => PuzzelSolverTests.cs} | 4 +- 02/CubeConundrum.Tests/PuzzleParserTests.cs | 8 +- 02/CubeConundrum/Program.cs | 144 +++++++++++++++++- 5 files changed, 201 insertions(+), 14 deletions(-) create mode 100644 02/CubeConundrum.Tests/GameTests.cs rename 02/CubeConundrum.Tests/{PartOnePuzzleSolverTests.cs => PuzzelSolverTests.cs} (97%) diff --git a/02/CubeConundrum.Tests/GameTests.cs b/02/CubeConundrum.Tests/GameTests.cs new file mode 100644 index 0000000..a3f8843 --- /dev/null +++ b/02/CubeConundrum.Tests/GameTests.cs @@ -0,0 +1,52 @@ +namespace CubeConundrum.Tests; + +public class GameTests +{ + [Theory, MemberData(nameof(TestData.Games), MemberType = typeof(TestData))] + public void PowerOfMinimumCubesNeeded_GivenAGame_ItShouldReturnTheSumOfTheMinimumCubesNeededForEachResult(Game game, int expected) + { + game.PowerOfMinimumCubesNeeded.Should().Be(expected); + } + + public static class TestData + { + public static readonly IEnumerable Games = new List + { + new object[] + { + new Game + { + Id = 1, + Results = + { + new() + { + Cubes = + { + new() { Count = 3, Color = CubeColor.Blue }, + new() { Count = 4, Color = CubeColor.Red } + } + }, + new() + { + Cubes = + { + new() { Count = 1, Color = CubeColor.Red }, + new() { Count = 2, Color = CubeColor.Green }, + new() { Count = 6, Color = CubeColor.Blue } + } + }, + new() + { + Cubes = + { + new() { Count = 2, Color = CubeColor.Green }, + } + } + } + }, + 48 + } + }; + } +} \ No newline at end of file diff --git a/02/CubeConundrum.Tests/ProgramTests.cs b/02/CubeConundrum.Tests/ProgramTests.cs index 5148b3d..09476f8 100644 --- a/02/CubeConundrum.Tests/ProgramTests.cs +++ b/02/CubeConundrum.Tests/ProgramTests.cs @@ -8,4 +8,11 @@ public class ProgramTests var result = await Program.Main(["INPUT.txt"]); result.Should().Be(2879); } + + [Fact] + public async Task Main_GivenInputAndPart2_ItShouldReturnExpectedSum() + { + var result = await Program.Main(["INPUT.txt", "part2"]); + result.Should().Be(65122); + } } \ No newline at end of file diff --git a/02/CubeConundrum.Tests/PartOnePuzzleSolverTests.cs b/02/CubeConundrum.Tests/PuzzelSolverTests.cs similarity index 97% rename from 02/CubeConundrum.Tests/PartOnePuzzleSolverTests.cs rename to 02/CubeConundrum.Tests/PuzzelSolverTests.cs index ba7acaa..e8ed0ba 100644 --- a/02/CubeConundrum.Tests/PartOnePuzzleSolverTests.cs +++ b/02/CubeConundrum.Tests/PuzzelSolverTests.cs @@ -1,8 +1,8 @@ namespace CubeConundrum.Tests; -public class PartOnePuzzleSolverTests +public class PuzzleSolverTests { - private readonly PartOnePuzzleSolver _sut = new(); + private readonly PuzzleSolver _sut = new(); [Theory, MemberData(nameof(TestData.Results), MemberType = typeof(TestData))] public void IsResultPossible_GivenAResult_ItShouldReturnExpectedOutcome(Result givenResult, bool expected) diff --git a/02/CubeConundrum.Tests/PuzzleParserTests.cs b/02/CubeConundrum.Tests/PuzzleParserTests.cs index 5ac4fa8..23d4066 100644 --- a/02/CubeConundrum.Tests/PuzzleParserTests.cs +++ b/02/CubeConundrum.Tests/PuzzleParserTests.cs @@ -5,7 +5,7 @@ public class PuzzleParserTests private readonly PuzzleParser _sut = new(); [Theory, MemberData(nameof(TestData.CubeStrings), MemberType = typeof(TestData))] - public void ParseCube_GivenAStringThatRepresentsACube_ItShouldReturnTheEquivalentCubeModel(string input, Cube expected) + public void ParseCube_GivenAStringThatRepresentsACube_ItShouldReturnTheEquivalentCubeModel(string input, CubeCollection expected) { var result = _sut.ParseCube(input); result.Should().BeEquivalentTo(expected); @@ -29,9 +29,9 @@ public class PuzzleParserTests { public static readonly IEnumerable CubeStrings = new List { - new object[] { "4 red", new Cube { Count = 4, Color = CubeColor.Red } }, - new object[] { "1 green", new Cube { Count = 1, Color = CubeColor.Green } }, - new object[] { "2 blue", new Cube { Count = 2, Color = CubeColor.Blue } } + new object[] { "4 red", new CubeCollection { Count = 4, Color = CubeColor.Red } }, + new object[] { "1 green", new CubeCollection { Count = 1, Color = CubeColor.Green } }, + new object[] { "2 blue", new CubeCollection { Count = 2, Color = CubeColor.Blue } } }; public static readonly IEnumerable ResultStrings = new List diff --git a/02/CubeConundrum/Program.cs b/02/CubeConundrum/Program.cs index b1d5b08..c9558a4 100644 --- a/02/CubeConundrum/Program.cs +++ b/02/CubeConundrum/Program.cs @@ -7,21 +7,24 @@ public class Program if (args.Length is 0) { Console.WriteLine("Please provide a path to the input file."); - return 1; + return -1; } if (File.Exists(args[0]) is false) { Console.WriteLine("The provided file does not exist."); - return 2; + return -2; } var puzzleParser = new PuzzleParser(); - var puzzleSolver = new PartOnePuzzleSolver(); + var puzzleSolver = new PuzzleSolver(); var input = await File.ReadAllLinesAsync(args[0]); var games = input.Select(puzzleParser.ParseGame); - var result = puzzleSolver.SumPossibleGameIds(games); + + var result = args.Length > 1 && args[1] == "part2" + ? puzzleSolver.SumGameMinimumPowers(games) + : puzzleSolver.SumPossibleGameIds(games); Console.WriteLine($"The sum of all possible game ids is {result}."); @@ -29,28 +32,78 @@ public class Program } } -public class PartOnePuzzleSolver +/// +/// Puzzle solver. +/// +public class PuzzleSolver { + /// + /// The maximum number of cubes that can be used in a game. + /// private readonly int _maxCubeCount = 39; + + /// + /// The maximum number of red cubes that can be used in a game. + /// private readonly int _maxRedCubeCount = 12; + + /// + /// The maximum number of green cubes that can be used in a game. + /// private readonly int _maxGreenCubeCount = 13; + + /// + /// The maximum number of blue cubes that can be used in a game. + /// private readonly int _maxBlueCubeCount = 14; + /// + /// Determines whether a result is possible. + /// + /// The result to check. + /// True if the result is possible, otherwise false. public bool IsResultPossible(Result result) => result.TotalCubeCount <= _maxCubeCount && result.RedCubeCount <= _maxRedCubeCount && result.GreenCubeCount <= _maxGreenCubeCount && result.BlueCubeCount <= _maxBlueCubeCount; + /// + /// Determines whether a game is possible. + /// + /// The game to check. + /// True if the game is possible, otherwise false. public bool IsGamePossible(Game game) => game.Results.All(IsResultPossible); + /// + /// Sums all possible game ids. + /// + /// The games to sum. + /// The sum of all possible game ids. public int SumPossibleGameIds(IEnumerable games) => games .Where(IsGamePossible) .Sum(g => g.Id); + + /// + /// Sums the minimum powers of all games. + /// + /// The games to sum. + /// The sum of the minimum powers of all games. + public int SumGameMinimumPowers(IEnumerable games) => games + .Select(g => g.PowerOfMinimumCubesNeeded) + .Sum(); } +/// +/// Puzzle parser responsible for parsing puzzle input. +/// public class PuzzleParser { - public Cube ParseCube(string cubeString) + /// + /// Parses a cube from a string. + /// + /// The string to parse. + /// An instance of . + public CubeCollection ParseCube(string cubeString) { var parts = cubeString.Split(' '); var count = int.Parse(parts[0]); @@ -63,6 +116,11 @@ public class PuzzleParser }; } + /// + /// Parses a result from a string. + /// + /// The string to parse. + /// An instance of . public Result ParseResult(string resultString) { var cubes = resultString @@ -77,6 +135,11 @@ public class PuzzleParser }; } + /// + /// Parses a game from a string. + /// + /// The string to parse. + /// An instance of . public Game ParseGame(string gameString) { var parts = gameString.Split(':'); @@ -95,30 +158,95 @@ public class PuzzleParser } } +/// +/// Represents a game. +/// public class Game { + /// + /// The id of the game. + /// public int Id { get; set; } + + /// + /// The results of the game. + /// public List Results { get; set; } = []; + + private int MinimumRedCubesNeeded => Results.Max(r => r.RedCubeCount); + private int MinimumGreenCubesNeeded => Results.Max(r => r.GreenCubeCount); + private int MinimumBlueCubesNeeded => Results.Max(r => r.BlueCubeCount); + + /// + /// The power of the minimum number of each cube type needed to play the game. + /// + public int PowerOfMinimumCubesNeeded => MinimumRedCubesNeeded * MinimumGreenCubesNeeded * MinimumBlueCubesNeeded; } +/// +/// Represents a result. +/// public class Result { - public List Cubes { get; set; } = []; + /// + /// The cubes in the result. + /// + public List Cubes { get; set; } = []; + + /// + /// The total number of cubes in the result. + /// public int TotalCubeCount => Cubes.Sum(c => c.Count); + + /// + /// The number of red cubes in the result. + /// public int RedCubeCount => Cubes.Where(c => c.Color == CubeColor.Red).Sum(c => c.Count); + + /// + /// The number of green cubes in the result. + /// public int GreenCubeCount => Cubes.Where(c => c.Color == CubeColor.Green).Sum(c => c.Count); + + /// + /// The number of blue cubes in the result. + /// public int BlueCubeCount => Cubes.Where(c => c.Color == CubeColor.Blue).Sum(c => c.Count); } -public class Cube +/// +/// Represents cubes of a given color. +/// +public class CubeCollection { + /// + /// The number of cubes. + /// public int Count { get; set; } + + /// + /// The color of the cubes. + /// public CubeColor Color { get; set; } } +/// +/// Represents a cube color. +/// public enum CubeColor { + /// + /// The red cube color. + /// Red, + + /// + /// The green cube color. + /// Green, + + /// + /// The blue cube color. + /// Blue } \ No newline at end of file From edfc99117b3287d240e825fd06d74e64d1f9fea8 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sat, 2 Dec 2023 12:49:34 -0600 Subject: [PATCH 7/7] docs: update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dac8b30..c5f76b3 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ This repository contains my solutions for the [Advent of Code 2023](https://adve | Day | Problem | Solution | Status | Notes | | --- | -------------------------- | :---------------------------------------: | :----: | ------------------------------------------------------------------- | | 01 | [Problem](./01/PROBLEM.md) | [Solution](./01/Trebuchet/Program.cs) | ✅ | The trickiest part here was accounting for overlapping digit words. | -| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/Program.cs) | ⌛ | +| 02 | [Problem](./02/PROBLEM.md) | [Solution](./02/CubeConundrum/Program.cs) | ✅ | The key to me here was to parse the input into a useful model. | | 03 | [Problem](./03/PROBLEM.md) | [Solution](./03/) | ⌛ | | 04 | [Problem](./04/PROBLEM.md) | [Solution](./04/) | ⌛ | | 05 | [Problem](./05/PROBLEM.md) | [Solution](./05/) | ⌛ |