Day 8: Seven Segment Search
Mix.install([:kino])
input = Kino.Input.textarea("Please paste your input:")
Part 1
inputs =
input
|> Kino.Input.read()
|> String.split([" | ", "\n"], trim: true)
|> Enum.map(fn patterns -> patterns |> String.split(" ") |> Enum.map(&String.graphemes/1) end)
|> Enum.chunk_every(2)
https://adventofcode.com/2021/day/8
Solve: Part 1
unique_sizes = [2, 3, 4, 7]
inputs
|> Enum.map(fn [_patterns, outputs] ->
outputs |> Enum.count(&(Enum.count(&1) in unique_sizes))
end)
|> Enum.sum()
Part 2
https://adventofcode.com/2021/day/8#part2
Solve: Part 2
defmodule SevenSegment do
def interpret(patterns) do
{pattern_1, rest_patterns} = find_1(patterns)
{pattern_4, rest_patterns} = find_4(rest_patterns)
{pattern_7, rest_patterns} = find_7(rest_patterns)
{pattern_8, rest_patterns} = find_8(rest_patterns)
{pattern_3, rest_patterns} = find_3(rest_patterns, pattern_7)
{pattern_9, rest_patterns} = find_9(rest_patterns, pattern_3)
{pattern_0, rest_patterns} = find_0(rest_patterns, pattern_1)
{pattern_6, rest_patterns} = find_6(rest_patterns)
{pattern_5, [pattern_2]} = find_5(rest_patterns, pattern_6)
[
pattern_0,
pattern_1,
pattern_2,
pattern_3,
pattern_4,
pattern_5,
pattern_6,
pattern_7,
pattern_8,
pattern_9
]
|> Enum.with_index()
end
def translate_output(output, interpreted_patterns) do
interpreted_patterns
|> Enum.find_value(fn {interpreted_pattern, number} ->
case equals?(interpreted_pattern, output) do
true -> number
_ -> nil
end
end)
end
defp find_1(patterns) do
find_by_count(patterns, 2)
end
defp find_4(patterns) do
find_by_count(patterns, 4)
end
defp find_7(patterns) do
find_by_count(patterns, 3)
end
defp find_8(patterns) do
find_by_count(patterns, 7)
end
defp find_3(patterns, pattern_7) do
index = patterns |> Enum.find_index(&(Enum.count(&1) == 5 and contains?(&1, pattern_7)))
List.pop_at(patterns, index)
end
defp find_9(patterns, pattern_3) do
find_by_contains(patterns, pattern_3)
end
defp find_0(patterns, pattern_1) do
find_by_contains(patterns, pattern_1)
end
defp find_6(patterns) do
find_by_count(patterns, 6)
end
defp find_5(patterns, pattern_6) do
index = patterns |> Enum.find_index(&contains?(pattern_6, &1))
List.pop_at(patterns, index)
end
defp find_by_count(patterns, count) do
index = patterns |> Enum.find_index(&(Enum.count(&1) == count))
List.pop_at(patterns, index)
end
defp find_by_contains(patterns, contained_pattern) do
index = patterns |> Enum.find_index(&contains?(&1, contained_pattern))
List.pop_at(patterns, index)
end
defp contains?(a, b) do
b -- a == []
end
defp equals?(a, b) do
contains?(a, b) and contains?(b, a)
end
end
_answer =
inputs
|> Enum.map(fn [patterns, outputs] ->
interpreted_patterns = SevenSegment.interpret(patterns)
outputs
|> Enum.map(&SevenSegment.translate_output(&1, interpreted_patterns))
|> Enum.reduce(0, fn x, acc ->
acc * 10 + x
end)
end)
|> Enum.sum()