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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Here’s my solution for Day 3:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule AdventOfCode.DayThree do
  def part_one(input) do
    input
    |&gt; parse_mul_instructions()
    |&gt; Enum.sum()
  end

  def part_two(input) do
    input
    |&gt; parse_mul_and_do_instructions()
    |&gt; Enum.reduce({:do, 0}, fn
      i, {_, acc} when is_atom(i) -&gt; {i, acc}
      n, {:do, acc} -&gt; {:do, n + acc}
      _, {:dont, acc} -&gt; {:dont, acc}
    end)
    |&gt; elem(1)
  end

  defp parse_mul_instructions(input) do
    regex = ~r/(mul)\((\d{1,3}),(\d{1,3})\)/

    regex
    |&gt; Regex.scan(input)
    |&gt; Enum.map(fn [_, _, n1, n2] -&gt;
      String.to_integer(n1) * String.to_integer(n2)
    end)
  end

  defp parse_mul_and_do_instructions(input) do
    regex = ~r/(mul\((\d{1,3}),(\d{1,3})\)|do\(\)|don'?t\(\))/

    regex
    |&gt; Regex.scan(input)
    |&gt; Enum.map(fn
      ["do()", _] -&gt; :do
      ["don't()", _] -&gt; :dont
      [_, _, n1, n2] -&gt; String.to_integer(n1) * String.to_integer(n2)
    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="348349" 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-2024-day-3/67837/52">Post #51</a>
	                </div>
	            </div>
              <div id="likers-container-348349" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="348349"
                     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 #51"></div>
  </section>
</div>
    <div class="postbit" id="348383" data-post-id="348383">
  <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 hardly ever use regex and haven’t written much Elixir recently, but this one went pretty quick once I figured out the regex bits. I also feel like Enum.map() is the only function I know for some reason. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">#Part 1
defmodule Day03 do
  def sum_input(input) do
    Regex.scan(~r/mul\(\d+,\d+\)/, input)
    |&gt; Enum.map(&amp;(Regex.scan(~r/\d+,\d+/, List.first(&amp;1)) |&gt; List.first() |&gt; List.first()))
    |&gt; Enum.map(&amp;String.replace(&amp;1, ",", "*"))
    |&gt; Enum.map(fn s -&gt; Code.eval_string(s) |&gt; elem(0) end)
    |&gt; Enum.sum()
  end
end

Day03.sum_input(input)


#Part 2
input = "do()" &lt;&gt; input &lt;&gt; "don't()"

Regex.scan(~r/do\(\)(.*?)don\'t\(\)/s, input)
|&gt; Enum.map(&amp;Day03.sum_input(List.first(&amp;1)))
|&gt; Enum.sum()
</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="348383" 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-2024-day-3/67837/53">Post #52</a>
	                </div>
	            </div>
              <div id="likers-container-348383" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="348383"
                     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 #52"></div>
  </section>
</div>
    <div class="postbit" id="348407" data-post-id="348407">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Day 3  we wrote another hand written parser becaus regexes suck. It uses the <a href="https://www.erlang.org/doc/system/binaryhandling.html#match-context" rel="nofollow">match context</a> which you can tell by compiling with the flag:</p>
<pre data-code-wrap="sh"><code class="lang-sh"># ERL_COMPILER_OPTIONS=bin_opt_info mix compile --force
</code></pre>
<p>It looks more verbose because of this, but essentially we keep an index of where in the string we are and use that to then extract data.</p>
<h3><a name="p-348407-part-1-1" class="anchor" href="#p-348407-part-1-1" aria-label="Heading link" rel="nofollow"></a>Part 1</h3>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def day_3_1() do
    "./day_3_input.txt"
    |&gt; File.read!()
    |&gt; parse(1, [], 0)
  end

  def parse(&lt;&lt;&gt;&gt;, _, _, total), do: total

  @mul_start "mul("
  @comma ","
  @mul_end ")"
  # If we see a mul start but the stack is not empty then it can't be valid.
  def parse(&lt;&lt;@mul_start, rest::binary&gt;&gt;, current_index, [], total) do
    new_current_index = current_index + 3
    end_index = parse_number(rest, new_current_index)

    if end_index == new_current_index do
      parse(rest, end_index, [], total)
    else
      &lt;&lt;number::binary-size(end_index - new_current_index), rest::binary&gt;&gt; = rest
      first_int = String.to_integer(number)
      parse(rest, end_index, [first_int], total)
    end
  end

  def parse(&lt;&lt;@comma, rest::binary&gt;&gt;, current_index, [first_int], total) do
    new_current_index = current_index + 1
    end_index = parse_number(rest, new_current_index)

    if end_index == new_current_index do
      parse(rest, current_index, [], total)
    else
      &lt;&lt;number::binary-size(end_index - new_current_index), rest::binary&gt;&gt; = rest
      second_int = String.to_integer(number)
      parse(rest, end_index, [second_int, first_int], total)
    end
  end

  def parse(&lt;&lt;@mul_end, rest::binary&gt;&gt;, current_index, [first, second], total) do
    parse(rest, current_index + 1, [], first * second + total)
  end

  # We reset the stack if we had started a mult that never happened.
  def parse(&lt;&lt;_::binary-size(1), rest::binary&gt;&gt;, index, _stack, total) do
    parse(rest, index + 1, [], total)
  end

  @all_digits ~c"0123456789"
  for digit &lt;- @all_digits do
    def parse_number(&lt;&lt;unquote(digit), rest::bits&gt;&gt;, end_index) do
      parse_number(rest, end_index + 1)
    end
  end

  def parse_number(_rest, end_index), do: end_index
</code></pre>
<h3><a name="p-348407-part-2-2" class="anchor" href="#p-348407-part-2-2" aria-label="Heading link" rel="nofollow"></a>Part 2</h3>
<p>Part two just adds a couple more functions to the mix, but repeated myself so part 1 still works on its own.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def day_3_2() do
    "./day_3_input.txt"
    |&gt; File.read!()
    |&gt; parse_instructions(1, [], 0)
  end

  def parse_instructions(&lt;&lt;&gt;&gt;, _, _, total), do: total

  @doo "do()"
  @dont "don't()"
  def parse_instructions(&lt;&lt;@dont, rest::binary&gt;&gt;, current_index, _, total) do
    parse_instructions(rest, current_index + 6, [:dont], total)
  end

  def parse_instructions(&lt;&lt;@doo, rest::binary&gt;&gt;, current_index, [:dont], total) do
    parse_instructions(rest, current_index + 3, [], total)
  end

  # Now if the stack has :dont in it we skip.
  def parse_instructions(&lt;&lt;_::binary-size(1), rest::binary&gt;&gt;, current_index, [:dont], total) do
    parse_instructions(rest, current_index + 1, [:dont], total)
  end

  def parse_instructions(&lt;&lt;@mul_start, rest::binary&gt;&gt;, current_index, [], total) do
    new_current_index = current_index + 3
    end_index = parse_number(rest, new_current_index)

    if end_index == new_current_index do
      parse_instructions(rest, end_index, [], total)
    else
      &lt;&lt;number::binary-size(end_index - new_current_index), rest::binary&gt;&gt; = rest
      first_int = String.to_integer(number)
      parse_instructions(rest, end_index, [first_int], total)
    end
  end

  def parse_instructions(&lt;&lt;@comma, rest::binary&gt;&gt;, current_index, [first_int], total) do
    new_current_index = current_index + 1
    end_index = parse_number(rest, new_current_index)

    if end_index == new_current_index do
      parse_instructions(rest, current_index, [], total)
    else
      &lt;&lt;number::binary-size(end_index - new_current_index), rest::binary&gt;&gt; = rest
      second_int = String.to_integer(number)
      parse_instructions(rest, end_index, [second_int, first_int], total)
    end
  end

  def parse_instructions(&lt;&lt;@mul_end, rest::binary&gt;&gt;, current_index, [first, second], total) do
    parse_instructions(rest, current_index + 1, [], first * second + total)
  end

  def parse_instructions(&lt;&lt;_::binary-size(1), rest::binary&gt;&gt;, index, _stack, total) do
    parse_instructions(rest, index + 1, [], total)
  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="348407" 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-2024-day-3/67837/54">Post #53</a>
	                </div>
	            </div>
              <div id="likers-container-348407" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="348407"
                     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 #53"></div>
  </section>
</div>
    <div class="postbit" id="348487" data-post-id="348487">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>You can make binary pattern matching much faster than regex. The latest json parser in otp doesn’t use regex and it’s rapid. I compared my part 1 to this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">  def regex() do
    problem =
      "./day_3_input.txt"
      |&gt; File.read!()
      |&gt; String.trim()

    ~r/mul\(([0-9]{1,3}),([0-9]{1,3})\)/
    |&gt; Regex.scan(problem)
    |&gt; Enum.reduce(0, fn [_, a, b], acc -&gt;
      String.to_integer(a) * String.to_integer(b) + acc
    end)
  end
</code></pre>
<p>And the results are:</p>
<pre data-code-wrap="sh"><code class="lang-sh">Operating System: macOS
CPU Information: Apple M1 Pro
Number of Available Cores: 8
Available memory: 16 GB
Elixir 1.15.2
Erlang 25.3
JIT enabled: false

Benchmark suite executing with the following configuration:
warmup: 2 s
time: 10 s
memory time: 2 s
reduction time: 2 s
parallel: 1
inputs: none specified
Estimated total run time: 32 s

Name             ips        average  deviation         median         99th %
Binary        2.54 K      394.40 μs   ±131.81%      369.29 μs      574.74 μs
Regex         1.88 K      531.98 μs    ±81.77%      505.54 μs      711.30 μs

Comparison:
Binary        2.54 K
Regex         1.88 K - 1.35x slower +137.58 μs

Memory usage statistics:

Name      Memory usage
Binary        57.45 KB
Regex        333.88 KB - 5.81x memory usage +276.43 KB

**All measurements for memory usage were the same**

Reduction count statistics:

Name   Reduction count
Binary         21.11 K
Regex          18.04 K - 0.85x reduction count -3.07300 K

**All measurements for reduction count were the same**
</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="348487" 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-2024-day-3/67837/55">Post #54</a>
	                </div>
	            </div>
              <div id="likers-container-348487" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="348487"
                     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 #54"></div>
  </section>
</div>
    <div class="postbit" id="348514" data-post-id="348514">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hello. I’m new and trying to learn. This was my first time writing Elixir, so I don’t know if this is how it’s supposed to be done. Be kind <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>For part 2 I decided to just remove the irrelevant parts of the input.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Three do
  def get_input do
    File.read!("./input.txt")
  end

  def extract_operations(input) do
    Regex.scan(~r/mul\((\d{1,3}),(\d{1,3})\)/, input)
    |&gt; Enum.map(fn [_op, num1, num2] -&gt;
      num1 = String.to_integer(num1)
      num2 = String.to_integer(num2)
      [num1 * num2]
    end)
  end

  def sum_products(ops) do
    List.flatten(ops)
    |&gt; Enum.filter(fn x -&gt; is_integer(x) end)
    |&gt; Enum.sum()
  end

  def part1 do
    extract_operations(get_input())
    |&gt; sum_products()
  end

  def part2 do
    String.split(get_input(), ~r/don\'t\(\)[\s\S]*?do\(\)/)
    |&gt; Enum.map(&amp;extract_operations/1)
    |&gt; sum_products()
  end
end

IO.puts("part 1: #{Three.part1()}")
IO.puts("part 2: #{Three.part2()}")

</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="348514" data-batch-url="/posts/batch_likers">
                        4
                      </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-2024-day-3/67837/56">Post #55</a>
	                </div>
	            </div>
              <div id="likers-container-348514" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="348514"
                     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 #55"></div>
  </section>
</div>
    <div class="postbit" id="348932" data-post-id="348932">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Pretty new to Elixir and using AOC to practice. Got the day 3 solution working with regexs to avoid having to track state.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Aoc2024.Day3 do
  @moduledoc false

  defp get_input(file) do
    File.read!(file)
  end

  defp parse_muls(data) do
    Regex.scan(~r/mul\((?&lt;a&gt;\d{1,3}),(?&lt;b&gt;\d{1,3})\)/, data)
  end

  defp mul([_, a, b]) do
    String.to_integer(a) * String.to_integer(b)
  end

  defp disable_instructions(data) do
    data
    |&gt; String.replace("\n", ".")
    |&gt; String.replace(~r/don't\(\).*do\(\)/U, ".")
    |&gt; String.replace(~r/don't\(\).*\z/, ".")
  end

  def part1(file) do
    get_input(file)
    |&gt; parse_muls()
    |&gt; Enum.map(&amp;mul/1)
    |&gt; Enum.sum()
  end

  def part2(file) do
    get_input(file)
    |&gt; disable_instructions()
    |&gt; parse_muls()
    |&gt; Enum.map(&amp;mul/1)
    |&gt; Enum.sum()
  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="348932" 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-2024-day-3/67837/57">Post #56</a>
	                </div>
	            </div>
              <div id="likers-container-348932" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="348932"
                     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 #56"></div>
  </section>
</div>
    <div class="postbit" id="348946" data-post-id="348946">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sevenseacat" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sevenseacat/120/23153_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sevenseacat
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Ash Framework</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>AOC is a great way to learn Elixir and get really familiar with the standard library! Nice work <img src="https://forum.elixirforum.com/images/emoji/apple/raising_hands.png?v=15" title=":raising_hands:" class="emoji" alt=":raising_hands:" 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="348946" 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-2024-day-3/67837/58">Post #57</a>
	                </div>
	            </div>
              <div id="likers-container-348946" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="348946"
                     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>