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

--- Day 8: Seven Segment Search ---

2021/day08.livemd

— Day 8: Seven Segment Search —

Setup

defmodule Setup do
  def get_input(prompt) do
    case IO.gets(prompt) do
      :eof -> ""
      line -> line <> get_input(prompt)
    end
  end

  def parse_input(input) do
    input
    |> String.split(["|", "\n"], trim: true)
    |> Enum.map(fn line ->
      line
      |> String.split(" ", trim: true)
    end)
    |> Enum.chunk_every(2)
    |> Enum.map(&amp;List.to_tuple/1)
  end
end

input = Setup.get_input("input") |> Setup.parse_input()
input
|> Enum.map(fn {_, out} -> out end)
|> List.flatten()
|> Enum.count(fn digit -> String.length(digit) in [2, 3, 4, 7] end)
defmodule DisplayFix do
  def parse_notes(notes) do
    notes =
      notes
      |> Enum.map(&amp;String.split(&amp;1, "", trim: true))
      |> Enum.group_by(&amp;length/1)

    nums = %{
      0 => nil,
      1 => hd(notes[2]),
      2 => nil,
      3 => Enum.find(notes[5], fn ds -> Enum.all?(hd(notes[2]), &amp;(&amp;1 in ds)) end),
      4 => hd(notes[4]),
      5 => nil,
      6 => Enum.find(notes[6], fn ds -> not Enum.all?(hd(notes[2]), &amp;(&amp;1 in ds)) end),
      7 => hd(notes[3]),
      8 => hd(notes[7]),
      9 => nil
    }

    [maybe_0, maybe_9] =
      (notes[6] -- [nums[6]])
      |> Enum.map(&amp;MapSet.new/1)

    nums =
      if Enum.count(MapSet.difference(maybe_0, MapSet.new(nums[3]))) == 2 do
        nums
        |> Map.put(0, maybe_0)
        |> Map.put(9, maybe_9)
      else
        nums
        |> Map.put(0, maybe_9)
        |> Map.put(9, maybe_0)
      end

    [maybe_2, maybe_5] =
      (notes[5] -- [nums[3]])
      |> Enum.map(&amp;MapSet.new/1)

    nums =
      if Enum.count(MapSet.difference(maybe_5, MapSet.new(nums[6]))) == 0 do
        nums
        |> Map.put(5, maybe_5)
        |> Map.put(2, maybe_2)
      else
        nums
        |> Map.put(5, maybe_2)
        |> Map.put(2, maybe_5)
      end

    Map.new(nums, fn
      {k, v} when is_list(v) -> {MapSet.new(v), k}
      {k, v} -> {v, k}
    end)
  end
end

# nums =
#   input
#   |> hd()
#   |> elem(0)
#   |> DisplayFix.parse_notes()

input
|> Enum.map(fn {inp, out} ->
  {DisplayFix.parse_notes(inp),
   out |> Enum.map(&amp;(&amp;1 |> String.split("", trim: true) |> MapSet.new()))}
end)
|> Enum.map(fn {mapping, out} ->
  Enum.map(out, &amp;mapping[&amp;1]) |> Enum.join() |> String.to_integer()
end)
|> Enum.sum()