<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="234076" data-post-id="234076">
  <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>Again, LiveBook:</p>
<hr>
<h2><a name="p-234076-day-4-1" class="anchor" href="#p-234076-day-4-1" aria-label="Heading link" rel="nofollow"></a>Day 4</h2>
<h3><a name="p-234076-input-2" class="anchor" href="#p-234076-input-2" aria-label="Heading link" rel="nofollow"></a>Input</h3>
<p>This time it is a little bit more convoluted, as there are 2 parts of the input.<br>
Fortunately we can easily disect the parts via pattern matching.</p>
<p>Technically the conversion to the numbers is not needed, but it does no harm<br>
and provides additional layer of safety against some whitespace characters left there<br>
and here.</p>
<p>The <code>Day4.win/2</code> function is manually unrolled, as it is easier to write than some<br>
random jumping in the list.</p>

<pre data-code-wrap="elixir"><code class="lang-elixir">[numbers | bingos] =
  File.read!("day4.txt")
  |&gt; String.split("\n\n", trim: true)

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

bingos =
  bingos
  |&gt; Enum.map(fn bingo -&gt;
    bingo
    |&gt; String.split(~r/\s+/, trim: true)
    |&gt; Enum.map(&amp;String.to_integer/1)
  end)

defmodule Day4 do
  def win(
        [
          a1, a2, a3, a4, a5,
          b1, b2, b3, b4, b5,
          c1, c2, c3, c4, c5,
          d1, d2, d3, d4, d5,
          e1, e2, e3, e4, e5
        ],
        nums
      ) do
    # Rows
    all_in([a1, a2, a3, a4, a5], nums) or
    all_in([b1, b3, b3, b4, b5], nums) or
    all_in([c1, c2, c3, c4, c5], nums) or
    all_in([d1, d2, d3, d4, d5], nums) or
    all_in([e1, e2, e3, e4, e5], nums) or
    # Columns
    all_in([a1, b1, c1, d1, e1], nums) or
    all_in([a2, b2, c2, d2, e2], nums) or
    all_in([a3, b3, c3, d3, e3], nums) or
    all_in([a4, b4, c4, d4, e4], nums) or
    all_in([a5, b5, c5, d5, e5], nums) or
    # Diagonals
    all_in([a1, b2, c3, d4, e5], nums) or
    all_in([a5, b4, c3, d2, e1], nums)
  end

  def not_matched(bingo, nums) do
    Enum.reject(bingo, &amp;(&amp;1 in nums))
  end

  defp all_in(list, nums) do
    Enum.all?(list, &amp;(&amp;1 in nums))
  end
end
</code></pre>
<h3><a name="p-234076-task-1-3" class="anchor" href="#p-234076-task-1-3" aria-label="Heading link" rel="nofollow"></a>Task 1</h3>
<p>We simply traverse the <code>numbers</code> list aggregating the numbers (order doesn’t really matter,<br>
here we aggregate them in reverse order to speedup the code). When we have enough numbers<br>
that any of the <code>bingos</code> is winning one, then we halt the reduction and return computed<br>
result.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">numbers
|&gt; Enum.reduce_while([], fn elem, acc -&gt;
  matches = [elem | acc]

  case Enum.find(bingos, &amp;Day4.win(&amp;1, matches)) do
    nil -&gt; {:cont, matches}
    bingo -&gt; {:halt, Enum.sum(Day4.not_matched(bingo, matches)) * elem}
  end
end)
</code></pre>
<h3><a name="p-234076-task-2-4" class="anchor" href="#p-234076-task-2-4" aria-label="Heading link" rel="nofollow"></a>Task 2</h3>
<pre data-code-wrap="elixir"><code class="lang-elixir">numbers
|&gt; Enum.reduce_while({bingos, []}, fn elem, {bingos, acc} -&gt;
  matches = [elem | acc]

  case bingos do
    [bingo] -&gt;
      if Day4.win(bingo, matches) do
        {:halt, Enum.sum(Day4.not_matched(bingo, matches)) * elem}
      else
        {:cont, {bingos, matches}}
      end

    _ -&gt;
      {:cont, {Enum.reject(bingos, &amp;Day4.win(&amp;1, matches)), matches}}
  end
end)
</code></pre>
<p>Whole project can be watched there - <a href="https://github.com/hauleth/advent-of-code/blob/master/2021/solutions.livemd" rel="noopener nofollow ugc">https://github.com/hauleth/advent-of-code/blob/master/2021/solutions.livemd</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="234076" data-batch-url="/posts/batch_likers">
                        3
                      </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-2021-day-4/44250/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-234076" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234076"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="234078" data-post-id="234078">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Aetherus" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Aetherus/120/17203_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Aetherus
                      <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>I’m surprised that you can work out the answers taking diagonals into account.</p>
<blockquote>
<p>If all numbers in any row or any column of a board are marked, that board <em>wins</em> . (Diagonals don’t count.)</p>
</blockquote>
<p>By the way, I also checked diagonals until I failed in Part 2. <img src="https://forum.elixirforum.com/images/emoji/apple/sweat_smile.png?v=15" title=":sweat_smile:" class="emoji" alt=":sweat_smile:" 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="234078" 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-2021-day-4/44250/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-234078" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234078"
                     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="234079" data-post-id="234079">
  <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>Ah, missed that. This probably is why I needed to spend a little more on Task 2, but in general it doesn’t change the result.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="234079" 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-2021-day-4/44250/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-234079" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234079"
                     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="234080" data-post-id="234080">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>You got lucky! Every user’s input is different and many people got stuck there <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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="234080" 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-2021-day-4/44250/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-234080" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234080"
                     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="234084" data-post-id="234084">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I represented the boards as binaries,</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">&lt;&lt;
 22, 13, 17, 11, 0,
  8,  2, 23,  4, 24,
 21,  9, 14, 16,  7,
  6, 10,  3, 18,  5,
  1, 12, 20, 15, 19
&gt;&gt;
</code></pre>
<p>where marked number becomes <code>&lt;&lt;-1::signed&gt;&gt;</code></p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defp mark_board(board, number) do
  String.replace(board, &lt;&lt;number&gt;&gt;, &lt;&lt;-1&gt;&gt;, global: false)
end
</code></pre>
<p>and used binary pattern matching to identify winners:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">marked_row = quote(do: &lt;&lt;-1::40-signed&gt;&gt;)

column_patterns = [
  quote(do: &lt;&lt;-1::signed, _, _, _, _&gt;&gt;),
  quote(do: &lt;&lt;_, -1::signed, _, _, _&gt;&gt;),
  quote(do: &lt;&lt;_, _, -1::signed, _, _&gt;&gt;),
  quote(do: &lt;&lt;_, _, _, -1::signed, _&gt;&gt;),
  quote(do: &lt;&lt;_, _, _, _, -1::signed&gt;&gt;)
]

winning_patterns =
  List.flatten([
    # rows
    quote(do: &lt;&lt;unquote(marked_row), _::bytes&gt;&gt;),
    quote(do: &lt;&lt;_::5-bytes, unquote(marked_row), _::bytes&gt;&gt;),
    quote(do: &lt;&lt;_::10-bytes, unquote(marked_row), _::bytes&gt;&gt;),
    quote(do: &lt;&lt;_::15-bytes, unquote(marked_row), _::bytes&gt;&gt;),
    quote(do: &lt;&lt;_::20-bytes, unquote(marked_row)&gt;&gt;),
    # columns
    for pattern &lt;- column_patterns do
      quote(do: &lt;&lt;unquote_splicing(List.duplicate(pattern, 5))&gt;&gt;)
    end
  ])

for pattern &lt;- winning_patterns do
  defp winner?(unquote(pattern)), do: true
end

defp winner?(&lt;&lt;_::25-bytes&gt;&gt;), do: false
</code></pre>
<p>To calculate the sum I used</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def unmarked_sum(board)
  Enum.sum(for &lt;&lt;cell::signed &lt;- board&gt;&gt;, cell &gt; 0, do: cell)
end
</code></pre>
<p><a href="https://github.com/ruslandoga/advent-2021-elixir/blob/72d6a1d2b98d5c5754630af06903da0e8e9ab7f4/lib/day4.ex" rel="noopener nofollow ugc">Full</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="234084" data-batch-url="/posts/batch_likers">
                        3
                      </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-2021-day-4/44250/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-234084" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234084"
                     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="234086" data-post-id="234086">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>My <a href="https://github.com/juanperi/advent_of_code/blob/master/2021/day_4.ex" rel="noopener nofollow ugc">solution</a><br>
I created a struct that contained a reverse index <code>{value -&gt; {row, col}}</code>, the sum of the fields, and the amount of unfinished columns and rows</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Board do
  defstruct [:index, :row_count, :column_count, :sum, :winner]
  def new(matrix)
  # Returns the updated board, marking it as a winner if one of it's columns or rows is completed
  def draw(board, number)
</code></pre>
<p>with that in place, the solution is</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">    {draws, boards} = Support.input()

    {winner, draw} =
      Enum.reduce_while(
        draws,
        boards,
        fn draw, boards -&gt;
          boards = Enum.map(boards, &amp;Board.draw(&amp;1, draw))
          winner = Enum.find(boards, &amp; &amp;1.winner)

          if winner do
            {:halt, {winner, draw}}
          else
            {:cont, boards}
          end
        end
      )

    IO.inspect(winner.sum * draw, label: "Part 1")

    {_, winner, draw} =
      Enum.reduce(
        draws,
        {boards, nil, nil},
        fn draw, {boards, last_winner, last_draw} -&gt;
          boards = Enum.map(boards, &amp;Board.draw(&amp;1, draw))
          {winners, boards_left} = Enum.split_with(boards, &amp; &amp;1.winner)
          winner = List.last(winners)

          if winner do
            {boards_left, winner, draw}
          else
            {boards_left, last_winner, last_draw}
          end
        end
      )

    IO.inspect(winner.sum * draw, label: "Part 2")
  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="234086" 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-2021-day-4/44250/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-234086" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234086"
                     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="234087" data-post-id="234087">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Aetherus" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Aetherus/120/17203_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Aetherus
                      <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>Wow, that was a whole lot of fun reading your solutions! I learned new ways of metaprogramming from your code. <img src="https://forum.elixirforum.com/images/emoji/apple/heart.png?v=15" title=":heart:" class="emoji" alt=":heart:" 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="234087" 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-2021-day-4/44250/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-234087" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234087"
                     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="234089" data-post-id="234089">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>My Liveview solution here: <a href="https://github.com/stefanluptak/advent-of-code/blob/main/day_04.livemd" rel="noopener nofollow ugc">https://github.com/stefanluptak/advent-of-code/blob/main/day_04.livemd</a></p>
<p>Surprisingly, this day puzzle was a lot more pleasant for me compared to the Day 03 (esp part 2). That frustrated me a lot. <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="234089" 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-2021-day-4/44250/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-234089" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234089"
                     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="234093" data-post-id="234093">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Did it in Livebook today:</p>
<p><a href="https://github.com/egze/aoc_live/blob/main/y2021/day_04.md" rel="noopener nofollow ugc">y2021/day_04.md</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="234093" 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-2021-day-4/44250/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-234093" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234093"
                     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 #20"></div>
  </section>
</div>
    <div class="postbit" id="234105" data-post-id="234105">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Once the Bingo module was written…</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Bingo do
  defdelegate new_board(list), as: :new, to: __MODULE__.Board
  defdelegate play(board, value), to: __MODULE__.Board
  defdelegate score(tuple), to: __MODULE__.Board
  defdelegate score(board, value), to: __MODULE__.Board

  defmodule Cell, do: defstruct [val: nil, marked: false]
  defmodule Board do
    @size 5
    alias Bingo.Cell
    defstruct [grid: %{}, win: false]

    def new(list) do
      {board, _} = Enum.reduce(list, {%__MODULE__{}, 0}, &amp;reducer/2)
      board
    end

    def play(%__MODULE__{grid: grid} = board, value) do
      case Enum.find(grid, fn {_coord, cell} -&gt; cell.val == value end) do
        {coord, cell} -&gt;
          new_grid = Map.put(grid, coord, %{cell | marked: true})
          %{board | grid: new_grid, win: is_winning(new_grid, coord)}
        nil -&gt; board
      end
    end

    def score({board, value}), do: score(board, value)
    def score(board, value) do
      board.grid
      |&gt; Enum.filter(fn {{_row, _col}, %{marked: marked}} -&gt; not marked end)
      |&gt; Enum.map(fn {_coord, cell} -&gt; cell.val end)
      |&gt; Enum.sum()
      |&gt; Kernel.*(value)
    end

    defp reducer(val, {board, current}) do
      grid = Map.put(board.grid, to_coord(current), %Cell{val: val})
      {%{board | grid: grid}, current + 1}
    end

    defp to_coord(index), do: {div(index, @size), rem(index, @size)}

    defp is_winning(grid, {row, col}) do
      Enum.all?(get_line(:row, grid, row), fn {_coord, cell} -&gt; cell.marked end) ||
      Enum.all?(get_line(:col, grid, col), fn {_coord, cell} -&gt; cell.marked end)
    end

    defp get_line(:row, grid, index),
      do: Enum.filter(grid, fn {{row, _col}, _cell} -&gt; row == index end)
    defp get_line(:col, grid, index),
      do: Enum.filter(grid, fn {{_row, col}, _cell} -&gt; col == index end)
  end
end
</code></pre>
<p>… the rest was simple</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Day4 do
  def part1 do
    {moves, boards} = load_data()
    {boards, move} = moves
    |&gt; Enum.reduce_while(boards, fn move, boards -&gt;
      boards = Enum.map(boards, &amp;Bingo.play(&amp;1, move))
      if Enum.any?(boards, &amp; &amp;1.win),
        do: {:halt, {boards, move}},
        else: {:cont, boards}
    end)
    boards
    |&gt; Enum.find(&amp; &amp;1.win)
    |&gt; Bingo.score(move)
  end

  def part2 do
    {moves, boards} = load_data()
    moves
    |&gt; Enum.reduce_while(boards, fn move, boards -&gt;
      boards = Enum.map(boards, &amp;Bingo.play(&amp;1, move))
      case boards do
        [%{win: true} = board] -&gt; {:halt, {board, move}}
        [board] -&gt; {:cont, [board]}
        boards -&gt; {:cont, Enum.filter(boards, &amp; not(&amp;1.win))}
      end
    end)
    |&gt; Bingo.score()
  end

  def load_data do
    "input.txt"
    |&gt; File.read!()
    |&gt; String.split("\n", trim: true)
    |&gt; sanitize()
  end

  defp sanitize([head | rows]) do
    moves = head
    |&gt; String.split(",", trim: true)
    |&gt; Enum.map(&amp; String.to_integer(&amp;1))

    boards = rows
    |&gt; Enum.map(&amp;String.split(&amp;1, " ", trim: true))
    |&gt; Enum.chunk_every(5)
    |&gt; Enum.map(&amp;sanitize_list/1)
    |&gt; Enum.map(&amp;Bingo.new_board(&amp;1))

    {moves, boards}
  end

  defp sanitize_list(list),
    do: Enum.flat_map(list, fn l -&gt; Enum.map(l, &amp; String.to_integer(&amp;1)) 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="234105" 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-2021-day-4/44250/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-234105" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="234105"
                     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 #21"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/44250/load_more?page=3">Load more posts</a>
</div></template></turbo-stream>