Skip to content

Commit 886f9f0

Browse files
Update docs on Thu Dec 11 09:51:17 UTC 2025
1 parent f1e0bd1 commit 886f9f0

1 file changed

Lines changed: 8 additions & 8 deletions

File tree

2025/10/index.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -277,15 +277,15 @@ <h2 id="problem-name">Factory</h2>
277277
<p><em>Visit the website for the full story and the <a href="https://adventofcode.com/2025/day/10">full puzzle</a> description.</em></p>
278278
<p>The first half of the problem was totally fine: we just had to find the combination with the minimal number of button presses.</p>
279279
<p>However, Part 2 was, in my view, against the spirit of Advent of Code.</p>
280-
<p>It’s clearly a linear algebra problem. The buttons form the <strong>matrix A</strong>. Each button gets a column in <strong>A</strong> with zeros and ones corresponding to the bits of the button.</p>
281-
<p>The desired joltage becomes the vector <strong>b</strong>.</p>
282-
<p>Then one needs to solve <strong>Ax = b</strong> such that the components of <strong>x</strong> are non-negative integers and <strong>Σ xᵢ</strong> is minimal.</p>
280+
<p>It’s clearly a linear algebra problem. The buttons form the matrix <code>A</code>. Each button gets a column in <code>A</code> with zeros and ones corresponding to the bits of the button.</p>
281+
<p>The desired joltage becomes the vector <code>b</code>.</p>
282+
<p>Then one needs to solve <code>Ax = b</code> such that the components of <code>x</code> are non-negative integers and <code>Σ xᵢ</code> is minimal.</p>
283283
<p>This is a textbook integer linear programming problem, trivially solved by an ILP solver, or in <a href="solve.py">my case</a> z3. But this is not how Advent of Code has worked in the last 10+ years, so I was hoping for some shortcut, maybe a special structure of the input, but no luck. This really seems to be the intended way.</p>
284-
<p>I did find another path, though, which is not that good-looking. One can notice that <strong>A</strong> is almost always full rank, and the kernel space has at most 2–3 dimensions.</p>
285-
<p>This means we can solve the equation using Gaussian elimination, which will give us a solution with the columns in the kernel set to 0. There is no guarantee that the solution is integer, or that all xᵢ are non-negative, though.</p>
286-
<p>But once the columns in the base and the kernel are identified, we form a square matrix <strong>B</strong> and move the remaining columns to <strong>K</strong>, then deal with <strong>Bx = b − Ky</strong>.</p>
287-
<p>Say that <strong>K</strong> has 3 columns. Now we can start brute-forcing by setting the values in <strong>y</strong> to some low integers: [1,0,0], [0,1,0], [0,0,1], then [1,1,0], [1,0,1], [0,1,1], [2,0,0], [0,2,0], [0,0,2], slowly increasing the sum of the values and solving for each combination.</p>
288-
<p>This way we eventually get a feasible solution for the original problem, say with the total button-press count equal to 100 or so. Then it’s enough to continue the above iteration while the sum of yᵢ is ≤ 100. That gives us a termination condition. During the search we might run into better solutions, which further lowers the upper bound.</p>
284+
<p>I did find another path, though, which is not that good-looking. One can notice that <code>A</code> is almost always full rank, and the kernel space has at most 2–3 dimensions.</p>
285+
<p>This means we can solve the equation using Gaussian elimination, which will give us a solution with the columns in the kernel set to 0. There is no guarantee that the solution is integer, or that all <code>xᵢ</code> are non-negative, though.</p>
286+
<p>But once the columns in the base and the kernel are identified, we form a square matrix <code>B</code> and move the remaining columns to <code>K</code>, then deal with <code>Bx = b − Ky</code>.</p>
287+
<p>Say that <strong>K</strong> has 3 columns. Now we can start brute-forcing by setting the values in <strong>y</strong> to some low integers: <code>[1,0,0]</code>, <code>[0,1,0]</code>, <code>[0,0,1]</code>, then <code>[1,1,0]</code>, <code>[1,0,1]</code>, <code>[0,1,1]</code>, <code>[2,0,0]</code>, <code>[0,2,0]</code>, <code>[0,0,2]</code>, slowly increasing the sum of the values and solving for each combination.</p>
288+
<p>This way we eventually get a feasible solution for the original problem, say with the total button-press count equal to 100 or so. Then it’s enough to continue the above iteration while the sum of <code>yᵢ</code> is ≤ 100. That gives us a termination condition. During the search we might run into better solutions, which further lowers the upper bound.</p>
289289
<p>I <a href="gauss.py">prototyped this idea</a> in Python with ChatGPT. I think, if anything, this could be ported to C#, but I don’t feel the urge. Although it uses first principles that one could potentially implement, it’s a much slower solution than the one using z3.</p>
290290
</div>
291291
<div id="code-container"><pre class="hljs language-csharp"><code>namespace AdventOfCode.Y2025.Day10;

0 commit comments

Comments
 (0)