Skip to content

Commit

Permalink
Solution for 2024-12-11 part 2
Browse files Browse the repository at this point in the history
Part 1 was deceitfully simple.
  • Loading branch information
tetsuo13 committed Dec 20, 2024
1 parent fa324e4 commit eb58faa
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 30 deletions.
86 changes: 58 additions & 28 deletions src/AdventOfCode/Calendar/Year2024/Day11/Solution.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,24 @@

namespace AdventOfCode.Calendar.Year2024.Day11;

/// <summary>
/// <para>
/// This puzzle is deceptively simple as solving part 1 can be done with just
/// a List. Should complete quickly and with little resources. The only change
/// in requirements for part 2 is a bump in the number of blinks, but it
/// causes a dramatic increase in memory and execution time, so much so that
/// it's almost guaranteed to exhaust memory. The solution created for part 1
/// won't work for part 2.
/// </para>
/// <para>
/// The basic idea behind the rewrite is to not maintain the collection of
/// stones per blink because it reaches 6 figures for 25 blinks and
/// exponentially grows. Rather, treat each stone individually since it
/// doesn't affect its neighbor anyway and maintain the number of stones it
/// evolves into. For part 2 this will end up with a dictionary of just under
/// 4,000 keys since there aren't that many permutations.
/// </para>
/// </summary>
[PuzzleInfo(2024, 11, "Plutonian Pebbles")]
public class Solution : BaseSolution
{
Expand All @@ -18,48 +36,60 @@ public override object Run(RunMode runMode)

return runMode switch
{
RunMode.PartOne => NumStones(initialArrangement, blinks),
RunMode.PartTwo => 0,
RunMode.PartOne => EvolveStones(initialArrangement, blinks),
RunMode.PartTwo => EvolveStones(initialArrangement, 75),
_ => throw new ArgumentOutOfRangeException(nameof(runMode))
};
}

private static int NumStones(string initialArrangement, int blinks)
private static long EvolveStones(string initialArrangement, int blinks)
{
var stones = initialArrangement.Split(' ')
// All unique stones and the total number of evolutions. Start with
// counting each stone in the initial arrangement once.
var stoneEvolutions = initialArrangement.Split(' ')
.Select(long.Parse)
.ToList();
.ToDictionary(stone => stone, _ => 1L);

for (int i = 0; i < blinks; i++)
// For each blink, create list of modifications of the overall
// evolutions and merge that back in.
for (var i = 0; i < blinks; i++)
{
stones = EvolveStones(stones);
}
var evolutionStage = new Dictionary<long, long>();

return stones.Count;
}
foreach (var stone in stoneEvolutions)
{
if (stone.Key == 0)
{
AddToOrCreate(evolutionStage, 1, stoneEvolutions[stone.Key]);
}
else
{
var numDigits = Math.Floor(Math.Log10(stone.Key)) + 1;

private static List<long> EvolveStones(List<long> stones)
{
var evolved = new List<long>();
if (numDigits % 2 == 0)
{
var d = (int)Math.Pow(10, numDigits / 2);
AddToOrCreate(evolutionStage, stone.Key / d, stone.Value);
AddToOrCreate(evolutionStage, stone.Key % d, stone.Value);
}
else
{
AddToOrCreate(evolutionStage, stone.Key * 2024, stone.Value);
}
}
}

stoneEvolutions = evolutionStage;
}

foreach (var stone in stones)
return stoneEvolutions.Values.Sum();

void AddToOrCreate(Dictionary<long, long> evolutions, long key, long value)
{
if (stone == 0)
{
evolved.Add(1);
}
else if (Math.Floor(Math.Log10(stone)) % 2 != 0)
if (!evolutions.TryAdd(key, value))
{
var evenStone = stone.ToString();
evolved.Add(int.Parse(evenStone[..(evenStone.Length / 2)]));
evolved.Add(int.Parse(evenStone[(evenStone.Length / 2)..]));
}
else
{
evolved.Add(stone * 2024);
evolutions[key] += value;
}
}

return evolved;
}
}
4 changes: 2 additions & 2 deletions tests/AdventOfCode.Tests/Calendar/Year2024/Day11Tests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ public void Example1()
{
string[] input = ["0 1 10 99 999"];
var solution = new SolutionTestWrapper<Solution>(input);
Assert.Equal(7, solution.Run(RunMode.PartOne));
Assert.Equal(7L, solution.Run(RunMode.PartOne));
}

[Fact]
public void Example2()
{
string[] input = ["125 17"];
var solution = new SolutionTestWrapper<Solution>(input);
Assert.Equal(55312, solution.Run(RunMode.PartOne));
Assert.Equal(55_312L, solution.Run(RunMode.PartOne));
}
}

0 comments on commit eb58faa

Please sign in to comment.