Sponsored by AppSignal
Would you like to see your link here? Contact us
Notesclub

Day 8

advent_of_code/2021/day-08.livemd

Day 8

Setup

Mix.install([
  {:kino, "~> 0.5.0"}
])
input = Kino.Input.textarea("Please paste your input:")
parsed =
  input
  |> Kino.Input.read()
  |> String.split([" |\n", " | ", "\n"], trim: true)
  |> Enum.chunk_every(2)
  |> Enum.map(fn [input, output] ->
    {input |> String.split() |> Enum.group_by(&byte_size/1, &String.to_charlist/1),
     output |> String.split() |> Enum.map(&String.to_charlist/1)}
  end)

Part 1

parsed
|> Enum.map(fn {_input, output} ->
  Enum.count(output, &(length(&1) in [2, 7, 3, 4]))
end)
|> Enum.sum()

Part 2

supersets = fn numbers, pivot ->
  Enum.filter(numbers, &match?([], pivot -- &1))
end

almost_supersets = fn numbers, pivot ->
  Enum.filter(numbers, &match?([_], pivot -- &1))
end

parsed
|> Enum.map(fn {input, output} ->
  %{
    2 => [one],
    3 => [seven],
    4 => [four],
    5 => two_three_five,
    6 => zero_six_nine,
    7 => [eight]
  } = input

  [nine] = supersets.(zero_six_nine, four)
  [six] = almost_supersets.(zero_six_nine, seven)
  [zero] = zero_six_nine -- [six, nine]

  [three] = supersets.(two_three_five, seven)
  [five] = almost_supersets.(two_three_five, six)
  [two] = two_three_five -- [three, five]

  numbers = %{
    Enum.sort(zero) => 0,
    Enum.sort(one) => 1,
    Enum.sort(two) => 2,
    Enum.sort(three) => 3,
    Enum.sort(four) => 4,
    Enum.sort(five) => 5,
    Enum.sort(six) => 6,
    Enum.sort(seven) => 7,
    Enum.sort(eight) => 8,
    Enum.sort(nine) => 9
  }

  [d1, d2, d3, d4] = output

  Integer.undigits([
    numbers[Enum.sort(d1)],
    numbers[Enum.sort(d2)],
    numbers[Enum.sort(d3)],
    numbers[Enum.sort(d4)]
  ])
end)
|> Enum.sum()