From 663bec9385655dba00cb2a0edcb6557c0081ad7d Mon Sep 17 00:00:00 2001 From: Andrei Nicholson Date: Fri, 5 Jan 2024 22:35:59 -0500 Subject: [PATCH] Refactor to split unit tests out to separate project --- AdventOfCode.sln | 8 ++++- README.md | 8 ++--- src/AdventOfCode/AdventOfCode.csproj | 16 ++++++++++ .../Calendar/2023/Day01/Solution.cs | 9 ++---- .../Calendar/2023/Day01/input.txt | 0 .../Calendar/2023/Day02/SetOfCubes.cs | 22 ++++++++++++++ .../Calendar/2023/Day02/Solution.cs | 29 +++---------------- .../Calendar/2023/Day02/input.txt | 0 .../Calendar/2023/Day03/Solution.cs | 14 ++++----- .../Calendar/2023/Day03/input.txt | 0 .../Calendar/2023/Day04/Scratchcard.cs | 8 +++++ .../Calendar/2023/Day04/Solution.cs | 9 +----- .../Calendar/2023/Day04/input.txt | 0 .../AdventOfCode}/Calendar/BaseSolution.cs | 2 +- {AdventOfCode => src/AdventOfCode}/Program.cs | 0 {AdventOfCode => src/AdventOfCode}/RunMode.cs | 0 .../AdventOfCode.Tests.csproj | 16 +++++----- .../Calendar/2023/Day01/SolutionTests.cs | 7 +++-- .../Calendar/2023/Day02/SolutionTests.cs | 7 +++-- .../Calendar/2023/Day03/SolutionTests.cs | 7 +++-- .../Calendar/2023/Day04/SolutionTests.cs | 7 +++-- 21 files changed, 98 insertions(+), 71 deletions(-) create mode 100644 src/AdventOfCode/AdventOfCode.csproj rename {AdventOfCode => src/AdventOfCode}/Calendar/2023/Day01/Solution.cs (93%) rename {AdventOfCode => src/AdventOfCode}/Calendar/2023/Day01/input.txt (100%) create mode 100644 src/AdventOfCode/Calendar/2023/Day02/SetOfCubes.cs rename {AdventOfCode => src/AdventOfCode}/Calendar/2023/Day02/Solution.cs (69%) rename {AdventOfCode => src/AdventOfCode}/Calendar/2023/Day02/input.txt (100%) rename {AdventOfCode => src/AdventOfCode}/Calendar/2023/Day03/Solution.cs (94%) rename {AdventOfCode => src/AdventOfCode}/Calendar/2023/Day03/input.txt (100%) create mode 100644 src/AdventOfCode/Calendar/2023/Day04/Scratchcard.cs rename {AdventOfCode => src/AdventOfCode}/Calendar/2023/Day04/Solution.cs (85%) rename {AdventOfCode => src/AdventOfCode}/Calendar/2023/Day04/input.txt (100%) rename {AdventOfCode => src/AdventOfCode}/Calendar/BaseSolution.cs (95%) rename {AdventOfCode => src/AdventOfCode}/Program.cs (100%) rename {AdventOfCode => src/AdventOfCode}/RunMode.cs (100%) rename AdventOfCode/AdventOfCode.csproj => tests/AdventOfCode.Tests/AdventOfCode.Tests.csproj (53%) rename {AdventOfCode => tests/AdventOfCode.Tests}/Calendar/2023/Day01/SolutionTests.cs (82%) rename {AdventOfCode => tests/AdventOfCode.Tests}/Calendar/2023/Day02/SolutionTests.cs (81%) rename {AdventOfCode => tests/AdventOfCode.Tests}/Calendar/2023/Day03/SolutionTests.cs (94%) rename {AdventOfCode => tests/AdventOfCode.Tests}/Calendar/2023/Day04/SolutionTests.cs (81%) diff --git a/AdventOfCode.sln b/AdventOfCode.sln index 834a717..6c7413b 100644 --- a/AdventOfCode.sln +++ b/AdventOfCode.sln @@ -3,7 +3,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34309.116 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdventOfCode", "AdventOfCode\AdventOfCode.csproj", "{B4A4D1C2-B2FD-4A90-9A3C-7F8D3DC1D212}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AdventOfCode", "src\AdventOfCode\AdventOfCode.csproj", "{B4A4D1C2-B2FD-4A90-9A3C-7F8D3DC1D212}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AdventOfCode.Tests", "tests\AdventOfCode.Tests\AdventOfCode.Tests.csproj", "{6AC23A70-AF1E-4F60-86F1-39A4F1310E6E}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -15,6 +17,10 @@ Global {B4A4D1C2-B2FD-4A90-9A3C-7F8D3DC1D212}.Debug|Any CPU.Build.0 = Debug|Any CPU {B4A4D1C2-B2FD-4A90-9A3C-7F8D3DC1D212}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4A4D1C2-B2FD-4A90-9A3C-7F8D3DC1D212}.Release|Any CPU.Build.0 = Release|Any CPU + {6AC23A70-AF1E-4F60-86F1-39A4F1310E6E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AC23A70-AF1E-4F60-86F1-39A4F1310E6E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AC23A70-AF1E-4F60-86F1-39A4F1310E6E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AC23A70-AF1E-4F60-86F1-39A4F1310E6E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index f805220..5e41f3f 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ Solutions to the [Advent of Code](https://adventofcode.com/) puzzles. | Puzzle | Solution | Date | Notes | | ------ | -------- | ---- | ----- | -| [Trebuchet?!](https://adventofcode.com/2023/day/1) | [Solution](./AdventOfCode/Calendar/2023/Day01/Solution.cs) | 2023-01 | Completed | -| [Cube Conundrum](https://adventofcode.com/2023/day/2) | [Solution](./AdventOfCode/Calendar/2023/Day02/Solution.cs) | 2023-02 | Completed | -| [Gear Ratios](https://adventofcode.com/2023/day/3) | [Solution](./AdventOfCode/Calendar/2023/Day03/Solution.cs) | 2023-03 | Incomplete | -| [Scratchcards](https://adventofcode.com/2023/day/4) | [Solution](./AdventOfCode/Calendar/2023/Day04/Solution.cs) | 2023-04 | Completed | +| [Trebuchet?!](https://adventofcode.com/2023/day/1) | [Solution](./src/AdventOfCode/Calendar/2023/Day01/Solution.cs) | 2023-01 | Completed | +| [Cube Conundrum](https://adventofcode.com/2023/day/2) | [Solution](./src/AdventOfCode/Calendar/2023/Day02/Solution.cs) | 2023-02 | Completed | +| [Gear Ratios](https://adventofcode.com/2023/day/3) | [Solution](./src/AdventOfCode/Calendar/2023/Day03/Solution.cs) | 2023-03 | Incomplete | +| [Scratchcards](https://adventofcode.com/2023/day/4) | [Solution](./src/AdventOfCode/Calendar/2023/Day04/Solution.cs) | 2023-04 | Completed | diff --git a/src/AdventOfCode/AdventOfCode.csproj b/src/AdventOfCode/AdventOfCode.csproj new file mode 100644 index 0000000..287cdc0 --- /dev/null +++ b/src/AdventOfCode/AdventOfCode.csproj @@ -0,0 +1,16 @@ + + + + Exe + net8.0 + enable + enable + + + + + Always + + + + diff --git a/AdventOfCode/Calendar/2023/Day01/Solution.cs b/src/AdventOfCode/Calendar/2023/Day01/Solution.cs similarity index 93% rename from AdventOfCode/Calendar/2023/Day01/Solution.cs rename to src/AdventOfCode/Calendar/2023/Day01/Solution.cs index 98f1d6c..8eee5d1 100644 --- a/AdventOfCode/Calendar/2023/Day01/Solution.cs +++ b/src/AdventOfCode/Calendar/2023/Day01/Solution.cs @@ -1,6 +1,6 @@ namespace AdventOfCode.Calendar._2023.Day01; -internal class Solution : BaseSolution +public class Solution : BaseSolution { private static readonly Dictionary _numberWords = new() { @@ -32,11 +32,8 @@ public override async Task Run(RunMode runMode) /// represent the tens place. The last number will be the ones place. /// private static int SumCalibrationValues(string[] inputLines) => - inputLines.Sum(line => - { - return 10 * AsNumber(line.First(char.IsDigit)) + - AsNumber(line.Last(char.IsDigit)); - }); + inputLines.Sum(line => 10 * AsNumber(line.First(char.IsDigit)) + + AsNumber(line.Last(char.IsDigit))); /// /// Make two passes against the line: forward from beginning to end looking diff --git a/AdventOfCode/Calendar/2023/Day01/input.txt b/src/AdventOfCode/Calendar/2023/Day01/input.txt similarity index 100% rename from AdventOfCode/Calendar/2023/Day01/input.txt rename to src/AdventOfCode/Calendar/2023/Day01/input.txt diff --git a/src/AdventOfCode/Calendar/2023/Day02/SetOfCubes.cs b/src/AdventOfCode/Calendar/2023/Day02/SetOfCubes.cs new file mode 100644 index 0000000..32d1c27 --- /dev/null +++ b/src/AdventOfCode/Calendar/2023/Day02/SetOfCubes.cs @@ -0,0 +1,22 @@ +using System.Reflection; + +namespace AdventOfCode.Calendar._2023.Day02; + +public sealed class SetOfCubes() +{ + public int Red { get; set; } + public int Green { get; set; } + public int Blue { get; set; } + +#pragma warning disable S1144 // Unused private types or members should be removed + public int this[string colorName] +#pragma warning restore S1144 // Unused private types or members should be removed + { + set + { + GetType() + .GetProperty(colorName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public) + !.SetValue(this, value, null); + } + } +} diff --git a/AdventOfCode/Calendar/2023/Day02/Solution.cs b/src/AdventOfCode/Calendar/2023/Day02/Solution.cs similarity index 69% rename from AdventOfCode/Calendar/2023/Day02/Solution.cs rename to src/AdventOfCode/Calendar/2023/Day02/Solution.cs index 33c7bae..c38b9c9 100644 --- a/AdventOfCode/Calendar/2023/Day02/Solution.cs +++ b/src/AdventOfCode/Calendar/2023/Day02/Solution.cs @@ -1,8 +1,6 @@ -using System.Reflection; +namespace AdventOfCode.Calendar._2023.Day02; -namespace AdventOfCode.Calendar._2023.Day02; - -internal class Solution : BaseSolution +public class Solution : BaseSolution { private readonly SetOfCubes _constraint = new() { @@ -11,25 +9,6 @@ internal class Solution : BaseSolution Blue = 14 }; - private sealed class SetOfCubes() - { - public int Red { get; set; } - public int Green { get; set; } - public int Blue { get; set; } - -#pragma warning disable S1144 // Unused private types or members should be removed - public int this[string colorName] -#pragma warning restore S1144 // Unused private types or members should be removed - { - set - { - GetType() - .GetProperty(colorName, BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public) - !.SetValue(this, value, null); - } - } - } - public override async Task Run(RunMode runMode) { var lines = await ReadInput(); @@ -65,9 +44,9 @@ private static int SumPowerSets(string[] lines) { var sum = 0; - for (var gameId = 0; gameId < lines.Length; gameId++) + foreach (var line in lines) { - var sets = SetsInGame(lines[gameId]); + var sets = SetsInGame(line); sum += sets.Max(x => x.Red) * sets.Max(x => x.Green) * sets.Max(x => x.Blue); } diff --git a/AdventOfCode/Calendar/2023/Day02/input.txt b/src/AdventOfCode/Calendar/2023/Day02/input.txt similarity index 100% rename from AdventOfCode/Calendar/2023/Day02/input.txt rename to src/AdventOfCode/Calendar/2023/Day02/input.txt diff --git a/AdventOfCode/Calendar/2023/Day03/Solution.cs b/src/AdventOfCode/Calendar/2023/Day03/Solution.cs similarity index 94% rename from AdventOfCode/Calendar/2023/Day03/Solution.cs rename to src/AdventOfCode/Calendar/2023/Day03/Solution.cs index 3aff36a..23b1f74 100644 --- a/AdventOfCode/Calendar/2023/Day03/Solution.cs +++ b/src/AdventOfCode/Calendar/2023/Day03/Solution.cs @@ -11,7 +11,7 @@ namespace AdventOfCode.Calendar._2023.Day03; /// than implementing algorithms from scratch [poorly] -- this really showed /// for part 2. /// -internal partial class Solution : BaseSolution +public partial class Solution : BaseSolution { private const char PeriodSymbol = '.'; private const char GearSymbol = '*'; @@ -74,7 +74,7 @@ private int SumGearRatios() _lines[lineNumber][match.Index - 2] != PeriodSymbol && !seen.Exists(x => x.Value == match.Value)) { - var rl = GearRatioRLRegex(); + var rl = GearRatioRightLeftRegex(); var rlMatches = rl.Match(_lines[lineNumber], match.Index); if (rlMatches.Success) @@ -89,7 +89,7 @@ private int SumGearRatios() if (boundingBox[(int)Direction.Right].Contains(GearSymbol) && _lines[lineNumber][match.Index + match.Value.Length + 1] != PeriodSymbol) { - var lr = GearRatioLRRegex(); + var lr = GearRatioLeftRightRegex(); var rlMatches = lr.Match(_lines[lineNumber], match.Index + match.Value.Length); if (rlMatches.Success) @@ -110,8 +110,8 @@ private int SumGearRatios() // to the right and left of it then concatenate them to // get the part number. - var lr = GearRatioLRRegex(); - var rl = GearRatioRLRegex(); + var lr = GearRatioLeftRightRegex(); + var rl = GearRatioRightLeftRegex(); var lrMatches = lr.Match(_lines[lineNumber + 2], match.Index + gearPosition); var rlMatches = rl.Match(_lines[lineNumber + 2], match.Index + gearPosition); @@ -199,8 +199,8 @@ private string[] GetBoundingBox(int currentLine, int matchIndex, string number) private static partial Regex NumberRegex(); [GeneratedRegex(@"\d+")] - private static partial Regex GearRatioLRRegex(); + private static partial Regex GearRatioLeftRightRegex(); [GeneratedRegex(@"\d+", RegexOptions.RightToLeft)] - private static partial Regex GearRatioRLRegex(); + private static partial Regex GearRatioRightLeftRegex(); } diff --git a/AdventOfCode/Calendar/2023/Day03/input.txt b/src/AdventOfCode/Calendar/2023/Day03/input.txt similarity index 100% rename from AdventOfCode/Calendar/2023/Day03/input.txt rename to src/AdventOfCode/Calendar/2023/Day03/input.txt diff --git a/src/AdventOfCode/Calendar/2023/Day04/Scratchcard.cs b/src/AdventOfCode/Calendar/2023/Day04/Scratchcard.cs new file mode 100644 index 0000000..fb5a655 --- /dev/null +++ b/src/AdventOfCode/Calendar/2023/Day04/Scratchcard.cs @@ -0,0 +1,8 @@ +namespace AdventOfCode.Calendar._2023.Day04; + +public class Scratchcard +{ + public IEnumerable WinningNumbers { get; set; } = Enumerable.Empty(); + public IEnumerable MyNumbers { get; set; } = Enumerable.Empty(); + public int Worth => (int)Math.Pow(2, WinningNumbers.Count() - 1); +} diff --git a/AdventOfCode/Calendar/2023/Day04/Solution.cs b/src/AdventOfCode/Calendar/2023/Day04/Solution.cs similarity index 85% rename from AdventOfCode/Calendar/2023/Day04/Solution.cs rename to src/AdventOfCode/Calendar/2023/Day04/Solution.cs index 106fe49..c2c60f2 100644 --- a/AdventOfCode/Calendar/2023/Day04/Solution.cs +++ b/src/AdventOfCode/Calendar/2023/Day04/Solution.cs @@ -1,14 +1,7 @@ namespace AdventOfCode.Calendar._2023.Day04; -internal class Solution : BaseSolution +public class Solution : BaseSolution { - private class Scratchcard - { - public IEnumerable WinningNumbers { get; set; } = Enumerable.Empty(); - public IEnumerable MyNumbers { get; set; } = Enumerable.Empty(); - public int Worth => (int)Math.Pow(2, WinningNumbers.Count() - 1); - } - public override async Task Run(RunMode runMode) { var scratchcards = await CountCards(); diff --git a/AdventOfCode/Calendar/2023/Day04/input.txt b/src/AdventOfCode/Calendar/2023/Day04/input.txt similarity index 100% rename from AdventOfCode/Calendar/2023/Day04/input.txt rename to src/AdventOfCode/Calendar/2023/Day04/input.txt diff --git a/AdventOfCode/Calendar/BaseSolution.cs b/src/AdventOfCode/Calendar/BaseSolution.cs similarity index 95% rename from AdventOfCode/Calendar/BaseSolution.cs rename to src/AdventOfCode/Calendar/BaseSolution.cs index 1e3ab5c..c685d83 100644 --- a/AdventOfCode/Calendar/BaseSolution.cs +++ b/src/AdventOfCode/Calendar/BaseSolution.cs @@ -12,7 +12,7 @@ public abstract class BaseSolution /// Input file will reside in a subdirectory of the executable. That /// path will follow the same as the namespace mostly. /// - public virtual async Task ReadInput() + protected virtual async Task ReadInput() { var solutionDirectory = GetType().Namespace! .Replace(nameof(AdventOfCode), string.Empty) diff --git a/AdventOfCode/Program.cs b/src/AdventOfCode/Program.cs similarity index 100% rename from AdventOfCode/Program.cs rename to src/AdventOfCode/Program.cs diff --git a/AdventOfCode/RunMode.cs b/src/AdventOfCode/RunMode.cs similarity index 100% rename from AdventOfCode/RunMode.cs rename to src/AdventOfCode/RunMode.cs diff --git a/AdventOfCode/AdventOfCode.csproj b/tests/AdventOfCode.Tests/AdventOfCode.Tests.csproj similarity index 53% rename from AdventOfCode/AdventOfCode.csproj rename to tests/AdventOfCode.Tests/AdventOfCode.Tests.csproj index 2d7889b..aeebfd8 100644 --- a/AdventOfCode/AdventOfCode.csproj +++ b/tests/AdventOfCode.Tests/AdventOfCode.Tests.csproj @@ -1,26 +1,28 @@ - + - Exe net8.0 enable enable - false + false + true - + + runtime; build; native; contentfiles; analyzers; buildtransitive all + + runtime; build; native; contentfiles; analyzers; buildtransitive + all - - Always - + diff --git a/AdventOfCode/Calendar/2023/Day01/SolutionTests.cs b/tests/AdventOfCode.Tests/Calendar/2023/Day01/SolutionTests.cs similarity index 82% rename from AdventOfCode/Calendar/2023/Day01/SolutionTests.cs rename to tests/AdventOfCode.Tests/Calendar/2023/Day01/SolutionTests.cs index c9d67cc..558fc32 100644 --- a/AdventOfCode/Calendar/2023/Day01/SolutionTests.cs +++ b/tests/AdventOfCode.Tests/Calendar/2023/Day01/SolutionTests.cs @@ -1,12 +1,13 @@ -using Xunit; +using AdventOfCode.Calendar._2023.Day01; +using Xunit; -namespace AdventOfCode.Calendar._2023.Day01; +namespace AdventOfCode.Tests.Calendar._2023.Day01; public class SolutionTests { private class TestSolution(string[] inputLines) : Solution { - public override Task ReadInput() => Task.FromResult(inputLines); + protected override Task ReadInput() => Task.FromResult(inputLines); } [Fact] diff --git a/AdventOfCode/Calendar/2023/Day02/SolutionTests.cs b/tests/AdventOfCode.Tests/Calendar/2023/Day02/SolutionTests.cs similarity index 81% rename from AdventOfCode/Calendar/2023/Day02/SolutionTests.cs rename to tests/AdventOfCode.Tests/Calendar/2023/Day02/SolutionTests.cs index 7c7b7d2..0145d2e 100644 --- a/AdventOfCode/Calendar/2023/Day02/SolutionTests.cs +++ b/tests/AdventOfCode.Tests/Calendar/2023/Day02/SolutionTests.cs @@ -1,12 +1,13 @@ -using Xunit; +using AdventOfCode.Calendar._2023.Day02; +using Xunit; -namespace AdventOfCode.Calendar._2023.Day02; +namespace AdventOfCode.Tests.Calendar._2023.Day02; public class SolutionTests { private class TestSolution(string[] inputLines) : Solution { - public override Task ReadInput() => Task.FromResult(inputLines); + protected override Task ReadInput() => Task.FromResult(inputLines); } private readonly string[] _input = diff --git a/AdventOfCode/Calendar/2023/Day03/SolutionTests.cs b/tests/AdventOfCode.Tests/Calendar/2023/Day03/SolutionTests.cs similarity index 94% rename from AdventOfCode/Calendar/2023/Day03/SolutionTests.cs rename to tests/AdventOfCode.Tests/Calendar/2023/Day03/SolutionTests.cs index 3397c83..cacc3fc 100644 --- a/AdventOfCode/Calendar/2023/Day03/SolutionTests.cs +++ b/tests/AdventOfCode.Tests/Calendar/2023/Day03/SolutionTests.cs @@ -1,12 +1,13 @@ -using Xunit; +using AdventOfCode.Calendar._2023.Day03; +using Xunit; -namespace AdventOfCode.Calendar._2023.Day03; +namespace AdventOfCode.Tests.Calendar._2023.Day03; public class SolutionTests { private class TestSolution(string[] inputLines) : Solution { - public override Task ReadInput() => Task.FromResult(inputLines); + protected override Task ReadInput() => Task.FromResult(inputLines); } [Theory] diff --git a/AdventOfCode/Calendar/2023/Day04/SolutionTests.cs b/tests/AdventOfCode.Tests/Calendar/2023/Day04/SolutionTests.cs similarity index 81% rename from AdventOfCode/Calendar/2023/Day04/SolutionTests.cs rename to tests/AdventOfCode.Tests/Calendar/2023/Day04/SolutionTests.cs index a00e281..1ec61d9 100644 --- a/AdventOfCode/Calendar/2023/Day04/SolutionTests.cs +++ b/tests/AdventOfCode.Tests/Calendar/2023/Day04/SolutionTests.cs @@ -1,12 +1,13 @@ -using Xunit; +using AdventOfCode.Calendar._2023.Day04; +using Xunit; -namespace AdventOfCode.Calendar._2023.Day04; +namespace AdventOfCode.Tests.Calendar._2023.Day04; public class SolutionTests { private class TestSolution(string[] inputLines) : Solution { - public override Task ReadInput() => Task.FromResult(inputLines); + protected override Task ReadInput() => Task.FromResult(inputLines); } [Theory]