<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="379770" data-post-id="379770">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mudasobwa" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mudasobwa/120/5298_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mudasobwa
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Cure</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>There is no interface, Cure invokes z3 via Erlang port <a href="https://github.com/am-kantox/cure-lang/blob/main/src%2Fsmt%2Fcure_smt_process.erl" rel="noopener nofollow ugc">https://github.com/am-kantox/cure-lang/blob/main/src%2Fsmt%2Fcure_smt_process.erl</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379770" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-379770" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379770"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="379772" data-post-id="379772">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="hauleth" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/hauleth/120/18942_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  hauleth
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Even with this PRs it doesn’t work, as the solver always used downloaded HiGHS binary instead of using user-provided one. In addition to that HiGHS 1.9.0 (which is downloaded) has some bug, which causes wrong result for my input, and if I change version to 1.12.0 it fails, as it requires additional external libraries (OpenBLAS IIRC). I have forked Dantzig to remove the HiGHS downloader (as it is working improperly anyway) in general and make it more into “CPLEX library” that can be then used with any solver and move solvers downloading and management to separate libs. Something like Nx or Ecto is doing. That way it can use Z3, HiGHS or anything else that can ingest this particular file format (and potentially implement other export formats as well).</p>
<p><a class="mention" href="/u/mudasobwa" rel="nofollow">@mudasobwa</a> I was also thinking about implementing SMT-LIB generator in Elixir, so it would provide a way to use any SMT solver with Elixir without worrying about compiling binaries and stuff.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379772" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-379772" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379772"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="379785" data-post-id="379785">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="antoine-duchenet" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/antoine-duchenet/120/27136_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  antoine-duchenet
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yes, my solution does not use any solver library:</p>
<div class="spoiler">
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Y2025.D10 do
  use Day, input: "2025/10", part1: ~c"l", part2: ~c"l"

  defp part2(input) do
    lines = input |&gt; parse_input() |&gt; Enum.with_index()

    lines
    |&gt; Map.new(fn {_, idx} -&gt; {idx, 1000} end)
    |&gt; Stream.unfold(fn old_map -&gt;
      new_map =
        Enum.reduce(lines, old_map, fn {l, idx}, acc -&gt;
          maybe_new_min = maybe_min_presses(l)
          Map.update!(acc, idx, &amp;min(&amp;1, maybe_new_min))
        end)

      old_sum = old_map |&gt; Map.values() |&gt; Enum.sum()
      new_sum = new_map |&gt; Map.values() |&gt; Enum.sum()

      {min(old_sum, new_sum), new_map}
    end)
    |&gt; Stream.map(&amp;IO.inspect/1)
    |&gt; Stream.transform({nil, 100, 100}, &amp;until_stable/2)
    |&gt; Enum.take(1)
    |&gt; hd()
  end

  defp until_stable(value, {last_value, requirement, count}) do
    case {value == last_value, count} do
      {true, 0} -&gt;
        {:halt, {value, requirement, count - 1}}

      {true, 1} -&gt;
        {[value], {value, requirement, count - 1}}

      {true, _} -&gt;
        {[], {value, requirement, count - 1}}

      {false, _} -&gt;
        {[], {value, requirement, requirement - 1}}
    end
  end

  defp maybe_min_presses(%{lights: _, buttons: buttons, requirements: requirements}) do
    target_map = index(requirements)

    repair(buttons, target_map)
  end

  defp repair(buttons, target_map) do
    [initial_candidate] =
      buttons
      |&gt; Enum.sort_by(&amp;Enum.count/1, :desc)
      |&gt; Enum.take(1)

    target_sum =
      target_map
      |&gt; Map.values()
      |&gt; Enum.sum()

    initial_presses = div(target_sum, length(initial_candidate))

    buttons_map =
      buttons
      |&gt; Enum.map(&amp;{&amp;1, if(&amp;1 == initial_candidate, do: initial_presses, else: 0)})
      |&gt; Map.new()

    initial_map =
      target_map
      |&gt; Map.keys()
      |&gt; Enum.map(&amp;if Enum.member?(initial_candidate, &amp;1), do: initial_presses, else: 0)
      |&gt; index()

    repair_rec(initial_map, target_map, buttons_map)
  end

  defp repair_rec(target_map, target_map, buttons_map) do
    buttons_map
    |&gt; Map.values()
    |&gt; Enum.sum()
  end

  defp repair_rec(current_map, target_map, buttons_map) do
    candidates =
      buttons_map
      |&gt; Map.keys()
      |&gt; Enum.map(&amp;{score(&amp;1, current_map, target_map), &amp;1})
      |&gt; Enum.sort_by(&amp;elem(&amp;1, 0), :desc)

    add = Enum.take(candidates, Enum.random(1..3))
    sub = Enum.take(candidates, -Enum.random(1..3))

    mutations =
      if Enum.random(0..3) == 0 do
        candidates
        |&gt; Enum.shuffle()
        |&gt; Enum.take(Enum.random(1..3))
      else
        []
      end

    {next_map, new_buttons_map} =
      add
      |&gt; Enum.concat(sub)
      |&gt; Enum.concat(mutations)
      |&gt; Enum.reduce({current_map, buttons_map}, &amp;apply_button/2)

    repair_rec(next_map, target_map, new_buttons_map)
  end

  defp apply_button({score, button}, {current_map, buttons_map}) do
    dir =
      cond do
        score &gt; 0 and Map.get(buttons_map, button) &gt; 0 and Enum.random(0..49) == 0 -&gt; -1
        score &gt; 0 -&gt; 1
        score &lt; 0 and Map.get(buttons_map, button) &gt; 0 -&gt; -1
        true -&gt; 0
      end

    new_map =
      Enum.reduce(button, current_map, fn idx, acc -&gt;
        Map.update!(acc, idx, &amp;(&amp;1 + dir))
      end)

    new_buttons_map = Map.update!(buttons_map, button, fn count -&gt; count + dir end)

    {new_map, new_buttons_map}
  end

  defp score(button, current_map, target_map) do
    Enum.reduce(button, 0, fn idx, acc -&gt;
      c = Map.fetch!(current_map, idx)
      t = Map.fetch!(target_map, idx)

      cond do
        c &lt; t -&gt;
          acc + Math.sqrt(t - c)

        c &gt; t -&gt;
          acc - Math.sqrt(c - t)

        true -&gt;
          acc
      end
    end)
  end

  defp index(lights) do
    lights
    |&gt; Enum.with_index()
    |&gt; Enum.reduce(%{}, fn {light, idx}, acc -&gt; Map.put(acc, idx, light) end)
  end

  defp parse_input(input), do: Enum.map(input, &amp;parse_line/1)

  defp parse_line(line) do
    [lights | rest] =
      ~r/[\[\(\{]([\d\.\#,]+)[\}\)\]]/
      |&gt; Regex.scan(line)
      |&gt; Enum.map(&amp;Enum.at(&amp;1, 1))

    {buttons, [requirements]} =
      rest
      |&gt; Enum.map(
        &amp;(&amp;1
          |&gt; Utils.splitrim(",")
          |&gt; Enum.map(fn num_str -&gt; String.to_integer(num_str) end))
      )
      |&gt; Enum.split(-1)

    %{lights: Utils.splitrim(lights, ""), buttons: buttons, requirements: requirements}
  end
end
</code></pre>
</div>
<p>It’s basically a recursive reparation approach with genetic programming inspiration. Those parameters converged “pretty quickly” :</p>
<ul>
<li>A single iteration takes around ~1 second, it processes all the machines</li>
<li>We wait for the minimum (sum) to be stable for 100 iterations</li>
<li>Each iteration “repairs” each machine until it reaches the target numeric counters state, keeping track of the button presses count</li>
<li>The initial state (numeric counters and presses count) is filled with a very rough approximation, it is reset on each reparation</li>
<li>Each reparation step <em>presses</em> between 1 and 3 buttons, prioritized by a score (how relevant each button is to converge)</li>
<li>Each reparation step <em>unpresses</em> between 1 and 3 buttons, prioritized by a score (how irrelevant each button is to converge)</li>
<li>There is 25% chance that 1 to 3 additional buttons (mutations) get triggered, <em>pressed</em> or <em>unpressed</em> depending on their relevance to converge</li>
<li>There is a slight 2% chance that any button that should be <em>pressed</em> would be <em>unpressed</em> (only if it can be unpressed, it helps to converge quicker by jumping out of rabbit holes caused by the very basic / poor scoring method)</li>
</ul>
<p>It took ~5min20sec to give the answer for my input, but I suspect it may vary a lot <img src="https://forum.elixirforum.com/images/emoji/apple/grin.png?v=15" title=":grin:" class="emoji" alt=":grin:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379785" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-379785" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379785"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="379875" data-post-id="379875">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Kevo" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Kevo
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="antoine-duchenet" data-post="14" data-topic="73612">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/antoine-duchenet/48/27136_2.png" class="avatar"> antoine-duchenet:</div>
<blockquote>
<p>It took ~5min20sec to give the answer for my input, but I suspect it may vary a lot <img src="https://forum.elixirforum.com/images/emoji/apple/grin.png?v=15" title=":grin:" class="emoji" alt=":grin:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>That seems pretty quick from where I’m at. I’m running it now and it does seem to be slowly working it’s way down to the correct result, but it’s been going for about 2 hours. It might take another hour or two to finally get to the right number at the rate it’s been counting down.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379875" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-379875" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379875"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="379890" data-post-id="379890">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="antoine-duchenet" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/antoine-duchenet/120/27136_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  antoine-duchenet
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I can’t say I’m surprised, the time it takes to converge vary a lot for my input and seems very sensible to the parameters (but I did not benchmark it cleanly, so it might just be an impression). It’s not a very reliable solution in its current state, and I’m not sure I’ll take time to improve it <img src="https://forum.elixirforum.com/images/emoji/apple/smiley.png?v=15" title=":smiley:" class="emoji" alt=":smiley:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379890" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-379890" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379890"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="379892" data-post-id="379892">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Kevo" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Kevo
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I let it run overnight and it was still working its way down toward the correct value, but I gave up on it in the end.  Still, I think it was a good attempt without using a solver. <img src="https://forum.elixirforum.com/images/emoji/apple/slightly_smiling_face.png?v=15" title=":slightly_smiling_face:" class="emoji" alt=":slightly_smiling_face:" loading="lazy" width="20" height="20"></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379892" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-379892" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379892"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="379971" data-post-id="379971">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="ironcamel" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ironcamel/120/33681_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  ironcamel
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m guessing this solution for part 2 did not work. The problem I see is that z3 doesn’t provide the actual optimal (minimum) value on it’s first run. It provides a guess at what the optimal value is. What the official z3 api bindings do is they repeatedly call z3 behind the scenes. Each time z3 is called, the previous value it returned is used to add a new constraint. This is repeated until the result doesn’t change.</p>
<p>For example, consider this z3 input which attempts to find the 2 integers which multiply to 24, and have the minimum sum:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">(declare-const x Int)
(declare-const y Int)
(assert (= (* x y) 24))
(assert (&gt; x 0))
(assert (&gt; y 0))
(minimize (+ x y))
(check-sat)
(get-model)
</code></pre>
<p>That outputs 8 and 3:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">(
  (define-fun x () Int
    8)
  (define-fun y () Int
    3)
)
</code></pre>
<p>This is obviously wrong because the sum of 8 and 3 is 11 which is not optimal. The optimal answer is 6 and 4 which has a sum of 10. To get the optimal value, you have to run z3 again with the added constraint that the next answer should try to be more optimal than the previous answer: <code>(assert (&lt; (+ x y) 11))</code></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">(declare-const x Int)
(declare-const y Int)
(assert (= (* x y) 24))
(assert (&gt; x 0))
(assert (&gt; y 0))
(minimize (+ x y))
(assert (&lt; (+ x y) 11))
(check-sat)
(get-model)
</code></pre>
<p>Now that will output the correct values of 6 and 4.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379971" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-379971" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379971"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="379973" data-post-id="379973">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="lud" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lud/120/14382_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  lud
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Well I added a unit test with my expected solution and it works 100% of times without a second call.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379973" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-379973" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379973"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="379979" data-post-id="379979">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Kevo" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Kevo
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>z3 worked on my input. I tried a couple of the different solver options in this thread, having no experience with any of them, and z3 was the only one that worked without error for me. Thanks btw, <a class="mention" href="/u/lud" rel="nofollow">@lud</a> . I fully expected it not to work on my input or to give me some error, but I just brew installed z3, set the path, and it worked on the first try. Now I just need to go back when I have time and dig into how it all works so I can actually understand it.</p>
<p>(Time, who has time? <img src="https://forum.elixirforum.com/images/emoji/apple/rofl.png?v=15" title=":rofl:" class="emoji" alt=":rofl:" loading="lazy" width="20" height="20">)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="379979" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-379979" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="379979"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="391265" data-post-id="391265">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="KeithFrost" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/KeithFrost/120/33263_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  KeithFrost
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I became obsessed with this problem after it took me a whole day to get a solution to Part 2.  I have now implemented three different solutions: one, an exceedingly clever one (I can say this, because I didn’t think of the algorithm) which extends the Part 1 solution by finding all of the ways (with 0 or 1 presses of each button) to match the least significant bits of the desired joltages, and then recursing on the now-even joltages divided by two, until the desired joltages are all zero.  I’ll post that one here, because it is the shortest self-contained solution (the other two are a long self-contained Elixir solution which implements Bareiss’s algorithm for reduction of integer matrices and then searches values of the remaining free variables for solutions, and another one that composes Prolog code that invokes SWI Prolog’s CLPQ solver).</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Machine do
  defstruct target: 0, buttons: %{}, joltages: %{}, parity_map: %{}

  def parse_target(target_str) do
    to_charlist(target_str)
      |&gt; Enum.with_index()
      |&gt; Enum.reduce(0, fn {ch, i}, t -&gt;
        case ch do
          ?. -&gt; 
            t
          ?# -&gt;
            Bitwise.bor(t, Bitwise.bsl(1, i))
        end
      end)
  end

  def parse_buttons(buttons_str) do
    Regex.scan(~r"\(([\d,]+)\)\s*", buttons_str)
      |&gt; Enum.map(fn [_match, button_str] -&gt;
        String.split(button_str, ",")
          |&gt; Enum.map(&amp;String.to_integer/1)
        end)
      |&gt; Enum.with_index(fn l, i -&gt; {i, MapSet.new(l)} end)
      |&gt; Map.new()
  end

  def parse_joltages(joltages_str) do
    String.split(joltages_str, ",")
      |&gt; Enum.map(&amp;String.to_integer/1)
      |&gt; Enum.with_index(fn jolt, i -&gt; {i, jolt} end)
      |&gt; Map.new()
  end
  
  def parse_line(line) do
    case Regex.run(~r"\[([.#]+)\]\s*([^{]+)\s*{([^}]+)}", line) do
      [_match, target_str, buttons_str, joltages_str] -&gt;
        %__MODULE__{
          target: parse_target(target_str),
          buttons: parse_buttons(String.trim(buttons_str)),
          joltages: parse_joltages(joltages_str)
        }
    end
  end

  def parse(lines) do
    Enum.map(lines, &amp;parse_line/1)
      |&gt; Enum.map(&amp;compute_parity_map/1)
  end

  def joltage_parity(joltages) do
    Enum.reduce(joltages, 0, fn {j, v}, parity -&gt;
      Bitwise.bor(parity, Bitwise.bsl(Bitwise.band(v, 1), j))
    end)
  end
  
  def count_bpushes(bpushed, acc \\ 0) do
    if bpushed == 0 do
      acc
    else
      bpushed = Bitwise.band(bpushed, bpushed - 1)
      count_bpushes(bpushed, acc + 1)
    end
  end

  def compute_parity_map(machine = %__MODULE__{buttons: buttons}) do
    bpush_options = 0..(Bitwise.bsl(1, map_size(buttons)) - 1)
    parity_map = Enum.reduce(bpush_options, %{}, fn bpushed, map -&gt;
      delta_jolts = Enum.reduce(buttons, %{}, fn {i, set}, djolts -&gt;
        if Bitwise.band(1, Bitwise.bsr(bpushed, i)) == 1 do
          Enum.reduce(set, djolts, fn j, djolts -&gt;
            Map.update(djolts, j, 1, fn v -&gt; v + 1 end)
          end)
        else
          djolts
        end
      end)
      parity = joltage_parity(delta_jolts)
      push_count = count_bpushes(bpushed)
      push = {push_count, bpushed, delta_jolts}
      Map.update(map, parity, [push], fn pushes -&gt; [push | pushes] end)
    end)
    %__MODULE__{machine | parity_map: parity_map}
  end

  def solve1(%__MODULE__{target: target, parity_map: parity_map}) do
    parity_map[target]
      |&gt; Enum.map(fn {push_count, _bpushed, _delta_jolts} -&gt; push_count end)
      |&gt; Enum.min()
  end

  def reduced_joltages(joltages, delta_jolts) do
    Enum.reduce(delta_jolts, joltages, fn {j, dv}, joltages -&gt;
      Map.update!(joltages, j, fn v -&gt; v - dv end)
    end)
  end

  def solve2(mach = %__MODULE__{joltages: joltages, parity_map: parity_map}) do
    if Enum.all?(joltages, fn {_j, v} -&gt; v == 0 end) do
      0
    else
      target = joltage_parity(joltages)
      push_options = Map.get(parity_map, target, [])
      Enum.map(push_options, fn {push_count, _bpushed, delta_jolts} -&gt;
        rjoltages = reduced_joltages(joltages, delta_jolts)
        {push_count, rjoltages}
      end)
        |&gt; Enum.reject(fn {_count, rjoltages} -&gt;
            Enum.any?(rjoltages, fn {j, v} -&gt;
              if Bitwise.band(v, 1) == 1, do: raise("odd joltage #{v} at #{j}")
              v &lt; 0
            end)
          end)
        |&gt; Enum.map(fn {count, rjoltages} -&gt;
            rjoltages = Enum.map(rjoltages, fn {j, v} -&gt; {j, Bitwise.bsr(v, 1)} end)
              |&gt; Map.new()
            count2 = solve2(%__MODULE__{mach | joltages: rjoltages})
            if count2 != nil do
              count + Bitwise.bsl(count2, 1)
            end
          end)
        |&gt; Enum.min(fn -&gt; nil end)
    end
  end
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="391265" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/advent-of-code-2025-day-10/73612/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-391265" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="391265"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>