Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us
Notesclub

Advent of Code Day 13

priv/livebooks/2022/day_13.livemd

Advent of Code Day 13

Mix.install([
  :kino,
  :jason
])

Input

raw_input = Kino.Input.textarea("Please paste your input here")
input = Kino.Input.read(raw_input)

Order Module

defmodule Ordering do
  def order([], []), do: nil
  def order([_ | _], []), do: false
  def order([], [_ | _]), do: true

  def order([x | x_rest], [y | y_rest]) when is_integer(x) and is_integer(y),
    do: (x == y &amp;&amp; order(x_rest, y_rest)) || x < y

  def order([x | x_rest], [y | y_rest]) when is_list(x) and is_list(y) do
    case(order(x, y)) do
      nil -> order(x_rest, y_rest)
      val -> val
    end
  end

  def order([x | x_rest], [y | y_rest]) when is_list(x) and is_integer(y),
    do: order([x | x_rest], [[y] | y_rest])

  def order([x | x_rest], [y | y_rest]) when is_integer(x) and is_list(y),
    do: order([[x] | x_rest], [y | y_rest])
end

Part 1

input
|> String.split(~r{(\r\n\r\n|\r\r|\n\n)})
|> Enum.map(fn pair ->
  [a, b] = String.split(pair, "\n")
  {Jason.decode!(a), Jason.decode!(b)}
end)
|> Enum.with_index(1)
|> Enum.filter(fn {{x, y}, _} -> Ordering.order(x, y) end)
|> Enum.map(&amp;elem(&amp;1, 1))
|> Enum.sum()

Part 2

input
|> String.split(~r{(\r\n\r\n|\r\r|\n\n)})
|> Enum.flat_map(&amp;String.split(&amp;1, "\n"))
|> Enum.map(&amp;Jason.decode!/1)
|> Kernel.++([[[2]], [[6]]])
|> Enum.sort_by(&amp;Function.identity/1, &amp;Ordering.order/2)
|> Enum.with_index(1)
|> Enum.filter(fn {elem, _} -> elem in [[[2]], [[6]]] end)
|> Enum.map(&amp;elem(&amp;1, 1))
|> Enum.product()