Refactor Day10 to replace `GetPatternCosts` with `GetButtonCombinations` and introduce `ButtonCombination` record for improved readability and modularity

This commit is contained in:
Sebastian Lindemeier 2025-12-12 20:19:45 +01:00
parent f4b5111fa0
commit 0d0d1b2150
1 changed files with 15 additions and 14 deletions

View File

@ -8,6 +8,7 @@ namespace AoC_2025;
public class Day10 : IPuzzleSolver<long>
{
private record ButtonCombination(uint Mask, int[] Joltages, int Cost);
private (bool[] lamps, int[][] buttons, int[] joltages)[] ParsePuzzleInput(string path)
{
var puzzleInput = File.ReadAllLines(path)
@ -80,20 +81,20 @@ public class Day10 : IPuzzleSolver<long>
private long GetMinCountButtonPressesForLamps(bool[] lamps, int[][] buttons)
{
var lampMask = AsMask(lamps, x => x);
var pattern = GetPatternCosts(lamps.Length, buttons)
.First(pattern => pattern.mask == lampMask);
return pattern.data.cost;
var pattern = GetButtonCombinations(lamps.Length, buttons)
.First(pattern => pattern.Mask == lampMask);
return pattern.Cost;
}
private long GetMinCountButtonPressesForJoltageLevels(int[] joltages, int[][] buttons)
{
var patternCosts = GetPatternCosts(joltages.Length, buttons)
.GroupBy(x => x.mask)
.ToDictionary(x => x.Key, x => x.Select(y => y.data).ToArray());
var res = GetMinCountInternal(joltages, patternCosts, new Dictionary<int[], long>(new IntArrayEqualityComparer()));
var buttonCombinations = GetButtonCombinations(joltages.Length, buttons)
.GroupBy(x => x.Mask)
.ToDictionary(x => x.Key, x => x.Select(y => y).ToArray());
var res = GetMinCountInternal(joltages, buttonCombinations, new Dictionary<int[], long>(new IntArrayEqualityComparer()));
return res;
static long GetMinCountInternal(int[] targetJoltages, Dictionary<uint, (int[] joltages, int cots)[]> patternCosts, Dictionary<int[], long> memory)
static long GetMinCountInternal(int[] targetJoltages, Dictionary<uint, ButtonCombination[]> buttonCombinations, Dictionary<int[], long> memory)
{
if (targetJoltages.Any(j => j < 0)) return 1_000_000_000L;
if (targetJoltages.All(j => j == 0)) return 0;
@ -101,11 +102,11 @@ public class Day10 : IPuzzleSolver<long>
var minCount = 1_000_000_000L;
var joltageMask = AsMask(targetJoltages, level => level % 2 == 1);
var patternsToCheck = patternCosts.GetValueOrDefault(joltageMask, []);
foreach (var (joltageLevels, cost) in patternsToCheck)
var combinationsToCheck = buttonCombinations.GetValueOrDefault(joltageMask, []);
foreach (var (_, joltageLevels, cost) in combinationsToCheck)
{
var nextTarget = targetJoltages.Zip(joltageLevels, (jolts, level) => (jolts - level) / 2).ToArray();
var nextCount = 2 * GetMinCountInternal(nextTarget, patternCosts, memory) + cost;
var nextCount = 2 * GetMinCountInternal(nextTarget, buttonCombinations, memory) + cost;
minCount = Math.Min(minCount, nextCount);
}
@ -114,16 +115,16 @@ public class Day10 : IPuzzleSolver<long>
}
}
private IEnumerable<(uint mask, (int[] joltageLevels, int cost) data)> GetPatternCosts(int patternLength, int[][] buttons)
private IEnumerable<ButtonCombination> GetButtonCombinations(int patternLength, int[][] buttons)
{
yield return (0,([..Enumerable.Repeat(0, patternLength)], 0));
yield return new ButtonCombination(0, [..Enumerable.Repeat(0, patternLength)], 0);
for (var i = 1; i <= buttons.Length; i++)
{
foreach (var buttonPattern in buttons.Combinations(i))
{
var joltageLevels = GetJoltageLevelsForButtonPattern(patternLength, buttonPattern);
var mask = AsMask(joltageLevels, level => level % 2 == 1);
yield return (mask,(joltageLevels, buttonPattern.Length));
yield return new ButtonCombination(mask, joltageLevels, buttonPattern.Length);
}
}