79 lines
1.9 KiB
Elixir
79 lines
1.9 KiB
Elixir
import AOC
|
|
|
|
aoc 2021, 8 do
|
|
def parse_line(line) do
|
|
[signal_patterns, output_value] = String.split(line, " | ")
|
|
|
|
signal_patterns = signal_patterns |> String.split(" ") |> Enum.map(&String.to_charlist/1)
|
|
output_value = output_value |> String.split(" ") |> Enum.map(&String.to_charlist/1)
|
|
|
|
{signal_patterns, output_value}
|
|
end
|
|
|
|
def parse_input() do
|
|
input_stream()
|
|
|> Stream.map(&parse_line/1)
|
|
end
|
|
|
|
def decode_digit_count([_, _]), do: 1
|
|
def decode_digit_count([_, _, _]), do: 1
|
|
def decode_digit_count([_, _, _, _]), do: 1
|
|
def decode_digit_count([_, _, _, _, _, _, _]), do: 1
|
|
def decode_digit_count(_word), do: 0
|
|
|
|
def infer_mappings(words) do
|
|
%{
|
|
2 => [one],
|
|
3 => [seven],
|
|
4 => [four],
|
|
5 => two_three_five,
|
|
6 => zero_six_nine,
|
|
7 => [eight]
|
|
} = Enum.group_by(words, &length/1)
|
|
|
|
{[three], two_five} = two_three_five |> Enum.split_with(&Enum.all?(one, fn x -> x in &1 end))
|
|
|
|
[b] = four -- three
|
|
|
|
{[five], [two]} = two_five |> Enum.split_with(&(b in &1))
|
|
|
|
{[nine], six_zero} = zero_six_nine |> Enum.split_with(&Enum.all?(four, fn x -> x in &1 end))
|
|
{[zero], [six]} = six_zero |> Enum.split_with(&Enum.all?(one, fn x -> x in &1 end))
|
|
|
|
%{
|
|
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
|
|
}
|
|
end
|
|
|
|
def p1 do
|
|
parse_input()
|
|
|> Enum.map(fn {_, output} ->
|
|
output
|
|
|> Enum.map(&decode_digit_count/1)
|
|
|> Enum.sum()
|
|
end)
|
|
|> Enum.sum()
|
|
end
|
|
|
|
def p2 do
|
|
parse_input()
|
|
|> Enum.map(fn {signals, output} ->
|
|
mappings = infer_mappings(signals)
|
|
|
|
for word <- output do
|
|
Map.get(mappings, Enum.sort(word))
|
|
end
|
|
|> Integer.undigits()
|
|
end)
|
|
|> Enum.sum()
|
|
end
|
|
end
|