mirror of
https://github.com/parnic/advent-of-code-2024.git
synced 2025-06-16 12:30:13 -05:00
Day 11
I'm reasonably satisfied with this. I saw the part 2 change coming, but still failed to prepare adequately, so my delta was higher than I wanted.
This commit is contained in:
112
src/11.cs
Normal file
112
src/11.cs
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
namespace aoc2024;
|
||||||
|
|
||||||
|
internal class Day11 : Day
|
||||||
|
{
|
||||||
|
private readonly Dictionary<long, long> stones = [];
|
||||||
|
|
||||||
|
internal override void Parse()
|
||||||
|
{
|
||||||
|
var lines = Util.Parsing.ReadAllText($"{GetDay()}");
|
||||||
|
var split = lines.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||||
|
foreach (var s in split)
|
||||||
|
{
|
||||||
|
stones.Add(long.Parse(s), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool HasEvenNumDigits(long v)
|
||||||
|
{
|
||||||
|
return v switch
|
||||||
|
{
|
||||||
|
< 100 and >= 10 => true,
|
||||||
|
< 10000 and >= 1000 => true,
|
||||||
|
< 1000000 and >= 100000 => true,
|
||||||
|
< 100000000 and >= 10000000 => true,
|
||||||
|
< 10000000000 and >= 1000000000 => true,
|
||||||
|
< 1000000000000 and >= 100000000000 => true,
|
||||||
|
< 100000000000000 and >= 10000000000000 => true,
|
||||||
|
< 10000000000000000 and >= 1000000000000000 => true,
|
||||||
|
< 1000000000000000000 and >= 100000000000000000 => true,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void Add(Dictionary<long, long> d, long v, long times)
|
||||||
|
{
|
||||||
|
if (!d.TryAdd(v, times))
|
||||||
|
{
|
||||||
|
d[v] += times;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Blink(Dictionary<long, long> modified, int times)
|
||||||
|
{
|
||||||
|
var cache = new Dictionary<long, (long, long)>();
|
||||||
|
|
||||||
|
for (int i = 0; i < times; i++)
|
||||||
|
{
|
||||||
|
var old = modified.ToDictionary();
|
||||||
|
foreach (var s in old)
|
||||||
|
{
|
||||||
|
if (s.Value == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.Key == 0)
|
||||||
|
{
|
||||||
|
modified[0] -= s.Value;
|
||||||
|
Add(modified, 1, s.Value);
|
||||||
|
}
|
||||||
|
else if (HasEvenNumDigits(s.Key))
|
||||||
|
{
|
||||||
|
var (left, right) = split(s.Key);
|
||||||
|
modified[s.Key] -= s.Value;
|
||||||
|
Add(modified, left, s.Value);
|
||||||
|
Add(modified, right, s.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
modified[s.Key] -= s.Value;
|
||||||
|
Add(modified, s.Key * 2024, s.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
|
||||||
|
(long, long) split(long v)
|
||||||
|
{
|
||||||
|
if (cache.TryGetValue(v, out var value))
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
var num = v.ToString();
|
||||||
|
var left = num[..(num.Length / 2)];
|
||||||
|
var right = num[(num.Length / 2)..];
|
||||||
|
cache[v] = (long.Parse(left), long.Parse(right));
|
||||||
|
return cache[v];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override string Part1()
|
||||||
|
{
|
||||||
|
var modified = stones.ToDictionary();
|
||||||
|
|
||||||
|
Blink(modified, 25);
|
||||||
|
|
||||||
|
var total = modified.Sum(x => x.Value);
|
||||||
|
return $"# stones after 25 blinks: <+white>{total}";
|
||||||
|
}
|
||||||
|
|
||||||
|
internal override string Part2()
|
||||||
|
{
|
||||||
|
var modified = stones.ToDictionary();
|
||||||
|
|
||||||
|
Blink(modified, 75);
|
||||||
|
|
||||||
|
var total = modified.Sum(x => x.Value);
|
||||||
|
return $"# stones after 75 blinks: <+white>{total}";
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user