feat: solved day 11 part 1 and part 2

This commit is contained in:
Stevan Freeborn
2024-12-12 00:01:22 -06:00
parent 2ed18de263
commit 31c55f5ec0
5 changed files with 151 additions and 68 deletions
+57 -3
View File
@@ -4,6 +4,54 @@ public class ObserverTests
{ {
private static readonly string[] ExampleInput = ["125", "17"]; private static readonly string[] ExampleInput = ["125", "17"];
private async Task<string> GetPuzzleInput()
{
return await File.ReadAllTextAsync(Path.Combine(AppContext.BaseDirectory, "INPUT.txt"));
}
[Test]
public async Task Blink_WhenCalledWithPuzzleInputAnd25Times_ItShouldReturnCorrectNumberOfStones()
{
var input = await GetPuzzleInput();
var stones = input
.Split(" ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
.Select(Stone.From)
.ToList();
var observer = Observer.Of(stones);
var result = observer.Blink(25);
await Assert.That(result).IsEqualTo(191690);
}
[Test]
public async Task Blink_WhenCalledWithPuzzleInputAnd75Times_ItShouldReturnCorrectNumberOfStones()
{
var input = await GetPuzzleInput();
var stones = input
.Split(" ", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries)
.Select(Stone.From)
.ToList();
var observer = Observer.Of(stones);
var result = observer.Blink(75);
await Assert.That(result).IsEqualTo(228651922369703);
}
[Test]
public async Task Blink_WhenCalledWithExampleInputAnd25Times_ItShouldReturnCorrectNumberOfStones()
{
var stones = ExampleInput.Select(Stone.From).ToList();
var observer = Observer.Of(stones);
var result = observer.Blink(25);
await Assert.That(result).IsEqualTo(55312);
}
[Test] [Test]
[MethodDataSource(nameof(BlinkTestCases))] [MethodDataSource(nameof(BlinkTestCases))]
public async Task Blink_WhenCalled_ItShouldReturnExpectedValue(BlinkTestCase testCase) public async Task Blink_WhenCalled_ItShouldReturnExpectedValue(BlinkTestCase testCase)
@@ -13,13 +61,19 @@ public class ObserverTests
var result = observer.Blink(testCase.NumberOfBlinks); var result = observer.Blink(testCase.NumberOfBlinks);
await Assert.That(result).IsEqualTo(testCase.ExpectedLineOfStones); await Assert.That(result).IsEqualTo(testCase.ExpectedNumberOfStones);
} }
public static IEnumerable<Func<BlinkTestCase>> BlinkTestCases() public static IEnumerable<Func<BlinkTestCase>> BlinkTestCases()
{ {
yield return () => new(ExampleInput, 0, "125 17"); yield return () => new(ExampleInput, 0, 2);
yield return () => new(ExampleInput, 1, 3);
yield return () => new(ExampleInput, 2, 4);
yield return () => new(ExampleInput, 3, 5);
yield return () => new(ExampleInput, 4, 9);
yield return () => new(ExampleInput, 5, 13);
yield return () => new(ExampleInput, 6, 22);
} }
public record BlinkTestCase(string[] Stones, int NumberOfBlinks, string ExpectedLineOfStones); public record BlinkTestCase(string[] Stones, int NumberOfBlinks, long ExpectedNumberOfStones);
} }
+45
View File
@@ -0,0 +1,45 @@
namespace PlutonianPebbles;
class Observer
{
private readonly List<Stone> _stones;
private Observer(List<Stone> stones)
{
_stones = stones;
}
public static Observer Of(List<Stone> stones) => new(stones);
public long Blink(int times)
{
var stoneCounts = _stones.GroupBy(s => s)
.ToDictionary(g => g.Key, g => (long)g.Count());
for (var blinks = 0; blinks < times; blinks++)
{
var nextCounts = new Dictionary<Stone, long>();
foreach (var (stone, count) in stoneCounts)
{
var transformed = stone.Transform();
foreach (var result in transformed)
{
if (nextCounts.ContainsKey(result))
{
nextCounts[result] += count;
}
else
{
nextCounts[result] = count;
}
}
}
stoneCounts = nextCounts;
}
return stoneCounts.Values.Sum();
}
}
+6 -64
View File
@@ -1,5 +1,7 @@
using System.Diagnostics; using System.Diagnostics;
using PlutonianPebbles;
if (args.Length is 0) if (args.Length is 0)
{ {
Console.WriteLine("Please provide a path to the input file."); Console.WriteLine("Please provide a path to the input file.");
@@ -25,69 +27,9 @@ var stones = input
var observer = Observer.Of(stones); var observer = Observer.Of(stones);
var result = observer.Blink(25); var times = isPart2 ? 75 : 25;
var result = observer.Blink(times);
stopwatch.Stop(); stopwatch.Stop();
Console.WriteLine($". ({stopwatch.ElapsedMilliseconds}ms)"); Console.WriteLine($"The number of stones is {result}. ({stopwatch.ElapsedMilliseconds}ms)");
class Observer
{
private readonly List<Stone> _stones;
private Observer(List<Stone> stones)
{
_stones = stones;
}
public static Observer Of(List<Stone> 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<Stone> 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;
}
}
+41
View File
@@ -0,0 +1,41 @@
namespace PlutonianPebbles;
record Stone
{
private readonly string _engravedValue;
private Stone(string engravedValue)
{
_engravedValue = engravedValue;
}
public static Stone From(string engraving) => new(engraving);
public List<Stone> Transform()
{
if (_engravedValue is "0")
{
return [new Stone("1")];
}
var hasOddNumberOfDigits = _engravedValue.Length % 2 is not 0;
if (hasOddNumberOfDigits)
{
var engravedNumber = long.Parse(_engravedValue);
var newEngravedValue = engravedNumber * 2024;
return [new(newEngravedValue.ToString())];
}
var middleIndex = _engravedValue.Length / 2;
var leftDigits = long.Parse(_engravedValue[..middleIndex]);
var rightDigits = long.Parse(_engravedValue[middleIndex..]);
return [new(leftDigits.ToString()), new(rightDigits.ToString())];
}
public override string ToString()
{
return _engravedValue;
}
}
+1
View File
@@ -54,3 +54,4 @@ dotnet build
| 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/ResonantCollinearity/) | Without some help from chat I don't know where I'd be...to be fair the description kind of mislead me. | | 08 | [Problem](./08/PROBLEM.md) | [Solution](./08/ResonantCollinearity/) | Without some help from chat I don't know where I'd be...to be fair the description kind of mislead me. |
| 09 | [Problem](./09/PROBLEM.md) | [Solution](./09/DiskFragmenter/) | Doing things with indexes is error prone. | | 09 | [Problem](./09/PROBLEM.md) | [Solution](./09/DiskFragmenter/) | Doing things with indexes is error prone. |
| 10 | [Problem](./10/PROBLEM.md) | [Solution](./10/HoofIt/) | I recognized the solution for this based on pattern from last year. Solved using BFS. | | 10 | [Problem](./10/PROBLEM.md) | [Solution](./10/HoofIt/) | I recognized the solution for this based on pattern from last year. Solved using BFS. |
| 11 | [Problem](./11/PROBLEM.md) | [Solution](./11/PlutonianPebbles/) | Dictionary > List |