From 2ed18de2638625a046ff99a61076a5023cb6f82f Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Wed, 11 Dec 2024 13:29:16 -0600 Subject: [PATCH] feat: work on day 11 part 1 --- 11/PlutonianPebbles.Tests/ObserverTests.cs | 25 ++++++++ 11/PlutonianPebbles.Tests/StoneTests.cs | 36 +++++++++++ 11/PlutonianPebbles/Program.cs | 75 +++++++++++++++++++++- 3 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 11/PlutonianPebbles.Tests/ObserverTests.cs create mode 100644 11/PlutonianPebbles.Tests/StoneTests.cs diff --git a/11/PlutonianPebbles.Tests/ObserverTests.cs b/11/PlutonianPebbles.Tests/ObserverTests.cs new file mode 100644 index 0000000..cdde5d2 --- /dev/null +++ b/11/PlutonianPebbles.Tests/ObserverTests.cs @@ -0,0 +1,25 @@ +namespace PlutonianPebbles.Tests; + +public class ObserverTests +{ + private static readonly string[] ExampleInput = ["125", "17"]; + + [Test] + [MethodDataSource(nameof(BlinkTestCases))] + public async Task Blink_WhenCalled_ItShouldReturnExpectedValue(BlinkTestCase testCase) + { + var stones = testCase.Stones.Select(Stone.From).ToList(); + var observer = Observer.Of(stones); + + var result = observer.Blink(testCase.NumberOfBlinks); + + await Assert.That(result).IsEqualTo(testCase.ExpectedLineOfStones); + } + + public static IEnumerable> BlinkTestCases() + { + yield return () => new(ExampleInput, 0, "125 17"); + } + + public record BlinkTestCase(string[] Stones, int NumberOfBlinks, string ExpectedLineOfStones); +} \ No newline at end of file diff --git a/11/PlutonianPebbles.Tests/StoneTests.cs b/11/PlutonianPebbles.Tests/StoneTests.cs new file mode 100644 index 0000000..4c2b648 --- /dev/null +++ b/11/PlutonianPebbles.Tests/StoneTests.cs @@ -0,0 +1,36 @@ +namespace PlutonianPebbles.Tests; + +public class StoneTests +{ + [Test] + public async Task ToString_WhenCalled_ItShouldReturnEngravedValue() + { + var engravedValue = "0"; + + var result = Stone.From(engravedValue).ToString(); + + await Assert.That(result).IsEqualTo(engravedValue); + } + + [Test] + [MethodDataSource(nameof(TransformTestCases))] + public async Task Transform_WhenCalled_ItShouldReturnStonedWithExpectedEngraving(TransformTestCase testCase) + { + var expected = testCase.TransformedValues.Select(Stone.From).ToList(); + + var result = Stone.From(testCase.EngravedValue).Transform(); + + await Assert.That(result).IsEquivalentTo(expected); + } + + public static IEnumerable> TransformTestCases() + { + yield return () => new("0", ["1"]); + yield return () => new("1", ["2024"]); + yield return () => new("10", ["1", "0"]); + yield return () => new("99", ["9", "9"]); + yield return () => new("999", ["2021976"]); + } + + public record TransformTestCase(string EngravedValue, List TransformedValues); +} \ No newline at end of file diff --git a/11/PlutonianPebbles/Program.cs b/11/PlutonianPebbles/Program.cs index 5f94bf8..a507b35 100644 --- a/11/PlutonianPebbles/Program.cs +++ b/11/PlutonianPebbles/Program.cs @@ -13,12 +13,81 @@ if (File.Exists(args[0]) is false) } var isPart2 = args.Length is 2 && args[1] is "part2"; -var input = await File.ReadAllLinesAsync(args[0]); +var input = await File.ReadAllTextAsync(args[0]); var stopwatch = new Stopwatch(); stopwatch.Start(); -// TODO: Implement solution +var stones = input + .Split(" ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries) + .Select(Stone.From) + .ToList(); + +var observer = Observer.Of(stones); + +var result = observer.Blink(25); stopwatch.Stop(); -Console.WriteLine($". ({stopwatch.ElapsedMilliseconds}ms)"); \ No newline at end of file +Console.WriteLine($". ({stopwatch.ElapsedMilliseconds}ms)"); + +class Observer +{ + private readonly List _stones; + + private Observer(List stones) + { + _stones = stones; + } + + public static Observer Of(List stones) => new(stones); + + public string Blink(int times) + { + if (times < 1) + { + return string.Join(" ", _stones); + } + + return string.Empty; + } +} + +record Stone +{ + private readonly string _engravedValue; + + private Stone(string engravedValue) + { + _engravedValue = engravedValue; + } + + public static Stone From(string engraving) => new(engraving); + + public List Transform() + { + if (_engravedValue is "0") + { + return [new Stone("1")]; + } + + var hasOddNumberOfDigits = _engravedValue.Length % 2 is not 0; + + if (hasOddNumberOfDigits) + { + var engravedNumber = int.Parse(_engravedValue); + var newEngravedValue = engravedNumber * 2024; + return [new(newEngravedValue.ToString())]; + } + + var middleIndex = _engravedValue.Length / 2; + var leftDigits = _engravedValue[..middleIndex].TrimStart('0'); + var rightDigits = _engravedValue[middleIndex..].TrimStart('0'); + + return [new(leftDigits), new(rightDigits)]; + } + + public override string ToString() + { + return _engravedValue; + } +} \ No newline at end of file