From 3af6cc3233c94275de61080f340a733e964c7020 Mon Sep 17 00:00:00 2001 From: Sebastian Lindemeier Date: Thu, 11 Dec 2025 12:05:45 +0100 Subject: [PATCH] Refactor Day10 to enhance button and joltage handling, implement Z3 solver for Part 2 logic, and update tests accordingly --- AoC_2025.Tests/Day10Test.cs | 8 ++--- AoC_2025/AoC_2025.csproj | 4 +++ AoC_2025/Day10.cs | 58 ++++++++++++++++++++++++++++++------- 3 files changed, 55 insertions(+), 15 deletions(-) diff --git a/AoC_2025.Tests/Day10Test.cs b/AoC_2025.Tests/Day10Test.cs index 41086b4..5dd4469 100644 --- a/AoC_2025.Tests/Day10Test.cs +++ b/AoC_2025.Tests/Day10Test.cs @@ -30,18 +30,18 @@ public class Day10Test } [Fact] - public void Part02_Test_equals_24() + public void Part02_Test_equals_33() { var actual = _sut.SolvePart2(TestInputPath); - Assert.Equal(24, actual); + Assert.Equal(33, actual); } [Fact] - public void Part02_Prod_equals_1568849600() + public void Part02_Prod_equals_19763() { var actual = _sut.SolvePart2(ProdInputPath); - Assert.Equal(1568849600, actual); + Assert.Equal(19763, actual); } } \ No newline at end of file diff --git a/AoC_2025/AoC_2025.csproj b/AoC_2025/AoC_2025.csproj index e85e30f..678a88a 100644 --- a/AoC_2025/AoC_2025.csproj +++ b/AoC_2025/AoC_2025.csproj @@ -10,4 +10,8 @@ + + + + diff --git a/AoC_2025/Day10.cs b/AoC_2025/Day10.cs index 39a9ecf..bbd975c 100644 --- a/AoC_2025/Day10.cs +++ b/AoC_2025/Day10.cs @@ -5,13 +5,13 @@ using System.Data.Common; using System.IO; using System.Linq; using AdvenOfCode.Contracts; +using Microsoft.Z3; namespace AoC_2025; public class Day10 : IPuzzleSolver { - private static int done = 0; - private (uint lamps, uint[] buttons, int[] joltages)[] ParsePuzzleInput(string path) + private (uint lamps, (int[] buttons, uint buttonsMap)[] buttons, int[] joltages)[] ParsePuzzleInput(string path) { var puzzleInput = File.ReadAllLines(path) .Where(line => !string.IsNullOrWhiteSpace(line)) @@ -35,7 +35,8 @@ public class Day10 : IPuzzleSolver .Select(button => button[1..^1] .Split(',', StringSplitOptions.RemoveEmptyEntries) .Select(lampIndex => int.Parse(lampIndex)) - .Aggregate((uint)0L, (acc, lampIndex) => acc | ((uint)1 << lampIndex))) + .ToArray()) + .Select(lampIndexes => (lampIndexes, lampIndexes.Aggregate((uint)0L, (acc, lampIndex) => acc | ((uint)1 << lampIndex)))) .ToArray()) .ToArray(); var joltages = puzzleInput @@ -55,19 +56,23 @@ public class Day10 : IPuzzleSolver public long SolvePart1(string pathToPuzzleInput) { var instructions = ParsePuzzleInput(pathToPuzzleInput); - Console.WriteLine($"total: {instructions.Length}"); var minCounts = instructions - .Select(ins => GetMinCountButtonPressesForLamps(ins.lamps, ins.buttons)) + .Select(ins => GetMinCountButtonPressesForLamps(ins.lamps, [..ins.buttons.Select(b => b.buttonsMap)])) .ToArray(); return minCounts.Sum(); } public long SolvePart2(string pathToPuzzleInput) { - return 0; + var instructions = ParsePuzzleInput(pathToPuzzleInput); + var minCounts = instructions + .Select(ins => GetMinCountButtonPressesForJoltages(ins.joltages, [..ins.buttons.Select(b => b.buttons)])) + .ToArray(); + var sum = minCounts.Sum(); + return sum; } - private static long GetMinCountButtonPressesForLamps(uint lamps, uint[] buttons) + private long GetMinCountButtonPressesForLamps(uint lamps, uint[] buttons) { var presses = 0L; HashSet lampStates = [lamps]; @@ -79,18 +84,49 @@ public class Day10 : IPuzzleSolver .ToHashSet(); presses++; } - - var amount = Interlocked.Increment(ref done); - Console.WriteLine($"done: {amount}, presses: {presses}"); return presses; } - private static uint[] GetLampStates(uint lampState, uint[] buttons) + private uint[] GetLampStates(uint lampState, uint[] buttons) { var states = buttons .Where(button => (lampState & button) > 0) .Select(button => lampState ^ button); return [..states]; } + + private long GetMinCountButtonPressesForJoltages(int[] joltages, int[][] buttons) + { + using var context = new Context(); + var optimize = context.MkOptimize(); + var variables = Enumerable.Range(0, buttons.Length) + .Select(ix => context.MkIntConst($"n{ix}")) + .ToArray(); + foreach (var variable in variables) + { + optimize.Add(variable >= 0); + } + + var zero = context.MkInt(0); + foreach (var (i, joltage) in joltages.Index()) + { + var equation = zero + zero; + + foreach (var (b, button) in buttons.Index()) + { + if(button.Contains(i)) + equation += variables[b]; + } + + optimize.Add(context.MkEq(equation, context.MkInt(joltage))); + } + var sumVariables = variables.Aggregate(zero + zero, (current, variable) => current + variable); + + optimize.MkMinimize(sumVariables); + optimize.Check(); + var answerExpression = optimize.Model.Eval(sumVariables); + var answer = answerExpression is IntNum number ? number.Int64 : 0; + return answer; + } } \ No newline at end of file