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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Not very pretty (planning to do some performance learning on this code layer maybe… (currently it takes 40s for the second task on a Ryzen 3900X)), but since nobody posted a <a href="https://en.wikipedia.org/wiki/CYK_algorithm" rel="noopener nofollow ugc">CYK</a> based solution, here is mine <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="ex"><code class="lang-ex">defmodule Aoc19 do
  defp parse_rule(rule) do
    [rule_no, rule] = String.split(rule, ": ")

    String.split(rule, " | ")
    |&gt; Enum.map(fn x -&gt; {rule_no, String.split(x, " ")} end)
  end

  def parse(file) do
    [rules, inputs] =
      File.stream!(file)
      |&gt; Stream.map(&amp;String.trim/1)
      |&gt; Stream.chunk_by(fn x -&gt; x == "" end)
      |&gt; Stream.reject(fn x -&gt; x == [""] end)
      |&gt; Enum.to_list()

    {rules |&gt; Enum.flat_map(&amp;parse_rule/1) |&gt; normalize(), inputs}
  end

  def normalize(rules) do
    rules_to_collapse =
      rules
      |&gt; Enum.filter(fn {_, rhs} -&gt;
        case rhs do
          [_, _] -&gt; false
          ["\"" &lt;&gt; &lt;&lt;_::bytes-size(1)&gt;&gt; &lt;&gt; "\""] -&gt; false
          _ -&gt; true
        end
      end)

    get_replacements = fn x -&gt;
      Enum.concat([x], Stream.filter(rules_to_collapse, fn {nt, _} -&gt; nt == x end) |&gt; Enum.map(fn {_, [r]} -&gt; r end))
    end

    rules
    |&gt; Stream.reject(fn x -&gt; Enum.member?(rules_to_collapse, x) end)
    |&gt; Stream.flat_map(fn orig = {nt, rhs} -&gt;
      case rhs do
        [a, b] -&gt;
          for new_a &lt;- get_replacements.(a),
              new_b &lt;- get_replacements.(b) do
            {nt, [new_a, new_b]}
          end
        _ -&gt; [orig]
      end
    end)
    |&gt; Enum.to_list()
  end

  def well_formed?(rules) do
    rules
    |&gt; Enum.reject(fn {_, rhs} -&gt;
      case rhs do
        ["\"a\""] -&gt; true
        ["\"b\""] -&gt; true
        [_, _] -&gt; true
        _ -&gt; false
      end
    end)
    |&gt; IO.inspect(label: "invalid")
    |&gt; Enum.count() == 0
  end

  def get_possible_productions(rules, i, lower_rows) do
    depth = Enum.count(lower_rows)
    cell_pairs_to_check =
      for d &lt;- 0..(depth - 1),
          potential_match1 &lt;-
            lower_rows
            |&gt; Enum.at(d)
            |&gt; Enum.at(i),
          potential_match2 &lt;-
            lower_rows
            |&gt; Enum.at(depth - d - 1)
            |&gt; Enum.at(i + (depth - d)) do
        {potential_match1, potential_match2}
      end
      |&gt; List.flatten()

    potentials_nts =
      cell_pairs_to_check
      |&gt; Stream.flat_map(fn {r1, r2} -&gt;
        Enum.filter(rules, fn {_, rhs} -&gt;
          [r1, r2] == rhs
        end)
        |&gt; Enum.map(fn {nt, _} -&gt; nt end)
      end)
      |&gt; Enum.filter(fn x -&gt; x != [] end)

    potentials_nts
  end

  def reverse_t_rule(rules, x) do
    Enum.find_value(rules, fn {nt, replacement} -&gt; if replacement == ["\"#{x}\""], do: nt end)
  end

  def matches?(rules, input) do
    n = String.length(input)

    to_nts = String.graphemes(input) |&gt; Enum.map(fn x -&gt; [reverse_t_rule(rules, x)] end)

    (n - 1)..1
    |&gt; Enum.reduce([to_nts], fn j, lower_rows -&gt;
      [
        for i &lt;- 0..(j - 1) do
          get_possible_productions(rules, i, lower_rows)
        end
        | lower_rows
      ]
    end)
    |&gt; Enum.at(0)
    |&gt; Enum.at(0)
    |&gt; Enum.any?(fn x -&gt; x == "0" end)
  end
end

</code></pre>
<p>I cheated for the second task by doing:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">11: 42 31 | 42 X
X: 11 31
</code></pre>
<p>(The normalize() function already was complex enough :P)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="198025" 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/avent-of-code-2020-day-19/36324/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-198025" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="198025"
                     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="198091" data-post-id="198091">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hallski, your solution saved me from banging my head against the wall for another couple hours. I had something very similar, but was returning results instead of concatenating them to a queue of actions. I was too stubborn to stop, but too burnt to re-evaluate. <img src="https://forum.elixirforum.com/images/emoji/apple/dizzy_face.png?v=15" title=":dizzy_face:" class="emoji" alt=":dizzy_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="198091" 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/avent-of-code-2020-day-19/36324/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-198091" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="198091"
                     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="198160" data-post-id="198160">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I think this is where my AoC journey stops this year…  Couldn’t make any headway into 19 or 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="198160" 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/avent-of-code-2020-day-19/36324/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-198160" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="198160"
                     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="198257" data-post-id="198257">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>If it is any consolation, Day 21 is a lot easier than 19 or 20. If you want to keep the party going, I would recommend skipping straight to it. (Plus, I hear there is some sort of crab fight on Day 22.)</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="198257" 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/avent-of-code-2020-day-19/36324/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-198257" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="198257"
                     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="198305" data-post-id="198305">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Papey" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Papey/120/20005_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Papey
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>+1 on that, 19 and 20 are hard because this is the last week-end of AOC. On week days they are always a little less intensive.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="198305" 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/avent-of-code-2020-day-19/36324/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-198305" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="198305"
                     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>