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

Day 13

day13.livemd

Day 13

Section

defmodule Day13 do
  def parse(input) do
    input
    |> String.split("\n\n", trim: true)
    |> Enum.map(fn packets ->
      [p1, p2] = String.split(packets, "\n", trim: true)
      {p1, _} = Code.eval_string(p1)
      {p2, _} = Code.eval_string(p2)

      {p1, p2}
    end)
  end

  def cmp(l, r)

  def cmp(l, r) when is_integer(l) and is_integer(r) do
    cond do
      l < r -> :lt
      l == r -> :eq
      l > r -> :gt
    end
  end

  def cmp(x, x), do: :eq

  def cmp([_ | _], []), do: :gt
  def cmp([], [_ | _]), do: :lt

  def cmp(l, r) when is_list(l) and is_integer(r),
    do: cmp(l, [r])

  def cmp(l, r) when is_list(r) and is_integer(l),
    do: cmp([l], r)

  def cmp([hl | tl], [hr | tr]) do
    case cmp(hl, hr) do
      :lt -> :lt
      :gt -> :gt
      :eq -> cmp(tl, tr)
    end
  end

  def part_1(input) do
    input
    |> parse()
    |> Enum.with_index(fn {p1, p2}, idx ->
      {cmp(p1, p2), idx + 1}
    end)
    |> Enum.reduce(0, fn {order, idx}, acc ->
      if order == :lt, do: acc + idx, else: acc
    end)
  end

  def part_2(input) do
    input
    |> parse()
    |> Enum.flat_map(&amp;Tuple.to_list/1)
    |> then(&amp;[[[2]], [[6]] | &amp;1])
    |> Enum.sort(&amp;(cmp(&amp;1, &amp;2) == :lt))
    |> Enum.with_index(1)
    |> Enum.filter(&amp;(elem(&amp;1, 0) in [[[2]], [[6]]]))
    |> Enum.map(&amp;elem(&amp;1, 1))
    |> Enum.product()
  end
end
test_input = """
[1,1,3,1,1]
[1,1,5,1,1]

[[1],[2,3,4]]
[[1],4]

[9]
[[8,7,6]]

[[4,4],4,4]
[[4,4],4,4,4]

[7,7,7,7]
[7,7,7]

[]
[3]

[[[]]]
[[]]

[1,[2,[3,[4,[5,6,7]]]],8,9]
[1,[2,[3,[4,[5,6,0]]]],8,9]
"""
Day13.part_1(test_input)
input = File.read!("day13_input.txt")
Day13.part_1(input)
Day13.part_2(test_input)
Day13.part_2(input)