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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>My beginner’s solution, Day12 part 1. Hot Springs<br>
It took a minute but it returned the correct answer <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">defmodule Day12 do

  def part1(input) do
    parse(input)
    |&gt; Enum.map(&amp;possible_arrangements/1)
    |&gt; Enum.sum
  end

  def possible_arrangements({springs, numbers}) do
    possibilities(springs)
    |&gt; Enum.filter(&amp;(valid?(&amp;1, numbers)))
    |&gt; Enum.count |&gt; tap(&amp;IO.puts(&amp;1))
  end

  def possibilities(springs, possible \\ [[]])
  def possibilities([], possible), do: possible
  def possibilities([:unknown | springs], possible) do
    variant1 = Enum.map(possible, fn x -&gt; x ++ [:damaged] end)
    variant2 = Enum.map(possible, fn x -&gt; x ++ [:operational] end)
    possibilities(springs, variant1 ++ variant2)
  end
  def possibilities([:damaged | springs], possible) do
    variant1 = Enum.map(possible, fn x -&gt; x ++ [:damaged] end)
    possibilities(springs, variant1)
  end
  def possibilities([:operational | springs], possible) do
    variant2 = Enum.map(possible, fn x -&gt; x ++ [:operational] end)
    possibilities(springs, variant2)
  end
      
  def valid?(springs, numbers) do
    springs
    |&gt; Enum.chunk_by(&amp;(&amp;1))
    |&gt; Enum.reject(fn s -&gt; Enum.all?(s, &amp;(&amp;1 == :operational)) end)
    |&gt; Enum.map(&amp;Enum.count/1)
    |&gt; Kernel.==(numbers)
  end

  def parse(raw_records) do 
    raw_records
    |&gt; String.split("\n")
    |&gt; Enum.map(&amp;parse_line/1)
  end
    
  def parse_line(raw_line) do
    [raw_chars, raw_numbers] = String.split(raw_line)

    numbers = raw_numbers
      |&gt; String.split(",")
      |&gt; Enum.map(&amp;String.to_integer/1)

    springs = raw_chars
      |&gt; String.graphemes
      |&gt; Enum.map(&amp;(case &amp;1 do
                     "." -&gt; :operational
                     "#" -&gt; :damaged
                     "?" -&gt; :unknown 
                    end))
    
    {springs, numbers}
  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="311132" 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-2023-day-12/60309/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-311132" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="311132"
                     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="311146" data-post-id="311146">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I solved it with Python first (was out and only computer I had was my wife’s who only had Python and R).</p>
<p>Today I had some free time and I wondered how a 1:1 Python to Elixir conversion would look like so I did:</p>
<p>I used Aja (perhaps I didn’t need to?) and also used <code>Process</code> for caching.</p>
<p><a href="https://github.com/code-shoily/advent_of_code/blob/master/lib/2023/day_12.ex" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/code-shoily/advent_of_code/blob/master/lib/2023/day_12.ex</a></p>
<p>I don’t have the Python version committed due to it being on a different computer but I do have screenshot of it</p>
<p></p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/f/5/f5c3d74867f05508feac294378ee4271dce00e61.jpeg" data-download-href="https://forum.elixirforum.com/uploads/default/f5c3d74867f05508feac294378ee4271dce00e61" title="IMG_1835" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/f/5/f5c3d74867f05508feac294378ee4271dce00e61_2_355x600.jpeg" alt="IMG_1835" data-base62-sha1="z48zbGMkXMXuidN2m99CLlYeAKZ" width="355" height="600" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/f/5/f5c3d74867f05508feac294378ee4271dce00e61_2_355x600.jpeg, https://forum.elixirforum.com/uploads/default/optimized/3X/f/5/f5c3d74867f05508feac294378ee4271dce00e61_2_532x900.jpeg 1.5x, https://forum.elixirforum.com/uploads/default/optimized/3X/f/5/f5c3d74867f05508feac294378ee4271dce00e61_2_710x1200.jpeg 2x" data-dominant-color="2D2E2F"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">IMG_1835</span><span class="informations">1214×2048 174 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p>
<p>I wish something like pythons cache decorator existed in Elixir. I looked into memoized but maybe I was using it wrong (it took forever). I will certainly scroll up and learn from you all.</p>
<p><s>Also Python takes 3 seconds vs Elixir’s 13 seconds. Same algorithm (literally mapped code). So I must be doing something wrong around the caching process (no pun intended) here.</s></p>
<p>Update: Ignore what I said before, I’m an idiot.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="311146" 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-2023-day-12/60309/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-311146" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="311146"
                     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="311225" data-post-id="311225">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I was not sure how to approach this, so I just did the dumb-guy brute-force method for part one. It takes about nine seconds to run on part one when I spawn a process per line. Unfortunately this dumb-guy approach doesn’t work on part 2. I quickly OOM it stops running. I’ll be looking at solutions here to learn how others are doing this.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule SpringParse do
  defp enum_repeat(enum, n) do
    for _ &lt;- 1..n do
      enum
    end
    |&gt; Enum.flat_map(&amp; &amp;1)
  end

  def into_spring_count(str) do
    str
      |&gt; String.split(".")
      |&gt; Stream.reject(&amp;(&amp;1 == ""))
      |&gt; Enum.map(&amp;String.length(&amp;1))
  end

  def generate(s) do
    chars = s |&gt; String.graphemes()

    q_map =
      for {{i, _}, j} &lt;-
            (for {q, i} &lt;- chars |&gt; Stream.with_index(), q == "?" do
               {i, q}
             end)
            |&gt; Stream.with_index(),
          into: %{} do
        {i, j}
      end

    possibilities = chars |&gt; Stream.filter(&amp;(&amp;1 == "?")) |&gt; Enum.count()

    for p &lt;- 0..(2 ** possibilities - 1) do
      for {l, i} &lt;- chars |&gt; Stream.with_index() do
        if l == "?" do
          case Bitwise.band(2 ** Map.get(q_map, i), p) do
            0 -&gt; "."
            n when n &gt; 0 -&gt; "#"
          end
        else
          l
        end
      end
    end
    |&gt; Stream.map(&amp;Enum.join(&amp;1, ""))
  end

  def parse(input) do
    input
    |&gt; String.split("\n")
    |&gt; Stream.reject(&amp;(&amp;1 === ""))
    |&gt; Stream.map(fn line -&gt;
      [pattern, exp] = line |&gt; String.split(" ")
      exp = String.split(exp, ",") |&gt; Enum.map(&amp;String.to_integer/1)
      [pattern, exp]
    end)
  end

  def parse_2(input) do
    input
    |&gt; String.split("\n")
    |&gt; Stream.reject(&amp;(&amp;1 == ""))
    |&gt; Stream.map(fn line -&gt;
      [pattern, exp] = line |&gt; String.split(" ")
      pattern = enum_repeat([pattern], 5) |&gt; Enum.join("?")
      exp = String.split(exp, ",") |&gt; Stream.map(&amp;String.to_integer/1) |&gt; enum_repeat(5)

      [pattern, exp]
    end)
  end

  def count_solutions(pattern, expectation) do
    matches =
      SpringParse.generate(pattern)
      |&gt; Stream.map(&amp;{&amp;1, SpringParse.into_spring_count(&amp;1)})
      |&gt; Stream.filter(&amp;(&amp;1 |&gt; elem(1) == expectation))

      Enum.count(matches)
    end

  def solve(input) do
    for [pattern, expectation] &lt;- parse(input),
        reduce: 0 do
      acc -&gt;
        acc + count_solutions(pattern, expectation)
    end
  end
end
</code></pre>
<p>with the parallelization code</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule SprintParseWorker do
  def loop_receive(n, acc) do
    case n do
      0 -&gt;
        acc

      _ -&gt;
        receive do
          m -&gt;
          loop_receive(n - 1, acc + m)
        end
    end
  end

  def solve_in_parallel(i) do
    parent = self()

    u = SpringParse.parse(i)

    pid_count =
    for [pattern, expectation] &lt;- u do
        spawn_link(fn -&gt;
            send(parent, SpringParse.count_solutions(pattern, expectation))
          end)
      end
      |&gt; Enum.count()

    loop_receive(pid_count, 0)
  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="311225" 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-2023-day-12/60309/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-311225" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="311225"
                     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="311442" data-post-id="311442">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I thought my part 1 was a slightly clever early terminating brute force search. Works pretty well but for part 2 it is way too slow on the real data. Not even sure how I can speed it up beyond running it on a machine with more than four cores to get more parallel.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Day12 do
  @moduledoc """
  Day12 AoC Solutions
  """

  alias AocToolbox.Input

  def input(:test),
    do: """
    ???.### 1,1,3
    .??..??...?##. 1,1,3
    ?#?#?#?#?#?#?#? 1,3,1,6
    ????.#...#... 4,1,1
    ????.######..#####. 1,6,5
    ?###???????? 3,2,1
    """

  def input(:test2),
    do: """
    ?###? 3
    ?###?????? 3,2
    ??????? 2,1
    ?###???????? 3,2,1
    """

  def input(:real), do: Input.load(__DIR__ &lt;&gt; "/input.txt")

  def solve(1, mode) do
    __MODULE__.Part1.solve(input(mode))
  end

  def solve(2, mode) do
    __MODULE__.Part2.solve(input(mode))
  end

  defmodule Part1 do
    def solve(input) do
      input
      |&gt; parse()
      |&gt; Enum.map(&amp;bfs/1)
      |&gt; Enum.sum()
    end

    def parse(input) do
      input
      |&gt; Input.Parser.parser()
      |&gt; elem(1)
    end

    def bfs([line, spec]) do
      do_bfs(line, spec)
    end

    defp do_bfs(line, spec, last \\ [])
    defp do_bfs([], [], _), do: 1
    defp do_bfs([], _spec, _), do: 0

    defp do_bfs(line, [], _) do
      if(Enum.any?(line, fn i -&gt; i == ?# end)) do
        0
      else
        1
      end
    end

    defp do_bfs([?? | rest] = _line, spec, []) do
      # + do_bfs(rest, spec, [?.])
      Task.async_stream([?#, ?.], fn i -&gt; do_bfs(rest, spec, [i]) end, timeout: :infinity)
      |&gt; Stream.map(fn
        {:ok, i} -&gt; i
        i -&gt; i
      end)
      |&gt; Enum.sum()
    end

    defp do_bfs([next | rest] = _line, spec, []) do
      do_bfs(rest, spec, [next])
    end

    defp do_bfs([next | rest] = line, [next_chunk | rest_chunks] = spec, [last | _] = chunk) do
      chunk_count = Enum.filter(chunk, fn i -&gt; i == ?# end) |&gt; Enum.count()

      case {next, last} do
        {??, ?#} -&gt;
          do_bfs([?. | rest], spec, chunk) +
            case next_chunk do
              n when n == chunk_count + 1 -&gt; do_bfs(rest, rest_chunks, [:no_hash_tag])
              n when n &gt; chunk_count + 1 -&gt; do_bfs([?# | rest], spec, chunk)
              _ -&gt; 0
            end

        {??, _} -&gt;
          do_bfs([?# | rest], spec, chunk) + do_bfs([?. | rest], spec, chunk)

        {?#, ?#} -&gt;
          case next_chunk do
            n when n == chunk_count + 1 -&gt;
              do_bfs(rest, rest_chunks, [:no_hash_tag])

            ^chunk_count -&gt;
              0

            _n -&gt;
              do_bfs(rest, spec, [next | chunk])
          end

        {?#, :no_hash_tag} -&gt;
          0

        {?#, ?.} -&gt;
          if next_chunk == 1 do
            do_bfs(rest, rest_chunks, [:no_hash_tag])
          else
            do_bfs(rest, spec, [next])
          end

        {?., ?#} when chunk_count &lt; next_chunk -&gt;
          0

        {?., ?#} when chunk_count == next_chunk -&gt;
          do_bfs(rest, rest_chunks, [next])

        {?., ?#} -&gt;
          0

        {?., ?.} -&gt;
          do_bfs(rest, spec, chunk)

        {?., :no_hash_tag} -&gt;
          do_bfs(rest, spec, [?.])
      end
    end
  end

  defmodule Part2 do
    def solve(input) do
      input
      |&gt; parse()
      |&gt; Enum.map(&amp;unfold/1)
      |&gt; Task.async_stream(&amp;Day12.Part1.bfs/1, timeout: :infinity)
      |&gt; Stream.map(fn {:ok, i} -&gt; i end)
      |&gt; Enum.sum()
    end

    defp parse(input) do
      input
      |&gt; Part1.parse()
    end

    defp unfold([springs, specs]),
      do: [
        List.duplicate(springs, 5) |&gt; Enum.intersperse([??]) |&gt; List.flatten(),
        List.duplicate(specs, 5) |&gt; List.flatten()
      ]
  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="311442" 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-2023-day-12/60309/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-311442" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="311442"
                     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="311546" data-post-id="311546">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Uggh. Finally got the caching solution to work after thoroughly reading every solution I could find. Ultimately <a class="mention" href="/u/woojiahao" rel="nofollow">@woojiahao</a>’s was the one that seemed to fit with my existing solution the easiest.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Day12 do
  @moduledoc """
  Day12 AoC Solutions
  """

  alias AocToolbox.Input

  def input(:test),
    do: """
    ???.### 1,1,3
    .??..??...?##. 1,1,3
    ?#?#?#?#?#?#?#? 1,3,1,6
    ????.#...#... 4,1,1
    ????.######..#####. 1,6,5
    ?###???????? 3,2,1
    """

  def input(:test2),
    do: """
    ?###? 3
    ?###?????? 3,2
    ??????? 2,1
    ?###???????? 3,2,1
    """

  def input(:real), do: Input.load(__DIR__ &lt;&gt; "/input.txt")

  def solve(1, mode) do
    __MODULE__.Part1.solve(input(mode))
  end

  def solve(2, mode) do
    __MODULE__.Part2.solve(input(mode))
  end

  defmodule Part1 do
    def solve(input) do
      input
      |&gt; parse()
      |&gt; Enum.map(&amp;bfs/1)
      |&gt; Enum.sum()
    end

    def parse(input) do
      input
      |&gt; Input.Parser.parser()
      |&gt; elem(1)
    end

    def bfs([line, spec], table_name \\ :cached) do
      :ets.new(table_name, [:set, :protected, :named_table])
      count = do_bfs(line, spec, table_name)
      :ets.delete(table_name)
      count
    end

    defp do_bfs(line, spec, last \\ [], table_name)
    defp do_bfs([], [], _, _), do: 1
    defp do_bfs([], _spec, _, _), do: 0

    defp do_bfs(line, [], _, _) do
      if(Enum.any?(line, fn i -&gt; i == ?# end)) do
        0
      else
        1
      end
    end

    defp do_bfs([?? | rest] = line, spec, [] = chunk, table_name) do
      key = {line, spec, chunk}
      cached = :ets.lookup(table_name, key)

      if length(cached) &gt; 0 do
        [{_, sub_count} | _] = cached
        sub_count
      else
        count = do_bfs(rest, spec, [?#], table_name) + do_bfs(rest, spec, [?.], table_name)
        :ets.insert(table_name, {key, count})
        count
      end
    end

    defp do_bfs([next | rest] = _line, spec, [], table_name) do
      do_bfs(rest, spec, [next], table_name)
    end

    defp do_bfs(
           [next | rest] = line,
           [next_chunk | rest_chunks] = spec,
           [last | _] = chunk,
           table_name
         ) do
      key = {line, spec, chunk}
      cached = :ets.lookup(table_name, key)

      if length(cached) &gt; 0 do
        [{_, sub_count} | _] = cached
        sub_count
      else
        chunk_count = Enum.filter(chunk, fn i -&gt; i == ?# end) |&gt; Enum.count()

        count =
          case {next, last} do
            {??, ?#} -&gt;
              do_bfs([?. | rest], spec, chunk, table_name) +
                case next_chunk do
                  n when n == chunk_count + 1 -&gt;
                    do_bfs(rest, rest_chunks, [:no_hash_tag], table_name)

                  n when n &gt; chunk_count + 1 -&gt;
                    do_bfs([?# | rest], spec, chunk, table_name)

                  _ -&gt;
                    0
                end

            {??, _} -&gt;
              do_bfs([?# | rest], spec, chunk, table_name) +
                do_bfs([?. | rest], spec, chunk, table_name)

            {?#, ?#} -&gt;
              case next_chunk do
                n when n == chunk_count + 1 -&gt;
                  do_bfs(rest, rest_chunks, [:no_hash_tag], table_name)

                ^chunk_count -&gt;
                  0

                _n -&gt;
                  do_bfs(rest, spec, [next | chunk], table_name)
              end

            {?#, :no_hash_tag} -&gt;
              0

            {?#, ?.} -&gt;
              if next_chunk == 1 do
                do_bfs(rest, rest_chunks, [:no_hash_tag], table_name)
              else
                do_bfs(rest, spec, [next], table_name)
              end

            {?., ?#} when chunk_count &lt; next_chunk -&gt;
              0

            {?., ?#} when chunk_count == next_chunk -&gt;
              do_bfs(rest, rest_chunks, [next], table_name)

            {?., ?#} -&gt;
              0

            {?., ?.} -&gt;
              do_bfs(rest, spec, chunk, table_name)

            {?., :no_hash_tag} -&gt;
              do_bfs(rest, spec, [?.], table_name)
          end

        :ets.insert(table_name, {key, count})
        count
      end
    end
  end

  defmodule Part2 do
    def solve(input) do
      input
      |&gt; parse()
      |&gt; Stream.map(&amp;unfold/1)
      |&gt; Stream.with_index()
      |&gt; Task.async_stream(
        fn {line, ndx} -&gt; Day12.Part1.bfs(line, String.to_atom("cache_#{ndx}")) end,
        timeout: :infinity
      )
      |&gt; Stream.map(fn {:ok, i} -&gt; i end)
      |&gt; Enum.sum()
    end

    defp parse(input) do
      input
      |&gt; Part1.parse()
    end

    defp unfold([springs, specs]),
      do: [
        List.duplicate(springs, 5) |&gt; Enum.intersperse([??]) |&gt; List.flatten(),
        List.duplicate(specs, 5) |&gt; List.flatten()
      ]
  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="311546" 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-2023-day-12/60309/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-311546" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="311546"
                     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="311949" data-post-id="311949">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="code-shoily" data-post="13" data-topic="60309">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/code-shoily/48/8052_2.png" class="avatar"> code-shoily:</div>
<blockquote>
<p>I wish something like pythons cache decorator existed in Elixir.</p>
</blockquote>
</aside>
<p>Maybe <code>Nebulex.Caching.Decorators</code> will work for you?</p>
<aside class="onebox allowlistedgeneric" data-onebox-src="https://nebulex.hexdocs.pm/Nebulex.Caching.Decorators.html">
  <header class="source">

      <a href="https://nebulex.hexdocs.pm/Nebulex.Caching.Decorators.html" target="_blank" rel="noopener nofollow ugc">nebulex.hexdocs.pm</a>
  </header>

  <article class="onebox-body">
    

<h3><a href="https://nebulex.hexdocs.pm/Nebulex.Caching.Decorators.html" target="_blank" rel="noopener nofollow ugc">Nebulex.Caching.Decorators — Nebulex v3.0.4</a></h3>



  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>
 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="311949" 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-2023-day-12/60309/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-311949" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="311949"
                     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>