Advent of Code 2021 - Day 8
Mix.install([
{:kino, "~> 0.6.1"}
])
Instructions
https://adventofcode.com/2021/day/8
Test Input
test_input = """
be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe
edbfga begcd cbg gc gcadebf fbgde acbgfd abcde gfcbed gfec | fcgedb cgb dgebacf gc
fgaebd cg bdaec gdafb agbcfd gdcbef bgcad gfac gcb cdgabef | cg cg fdcagb cbg
fbegcd cbd adcefb dageb afcb bc aefdc ecdab fgdeca fcdbega | efabcd cedba gadfec cb
aecbfdg fbg gf bafeg dbefa fcge gcbea fcaegb dgceab fcbdga | gecf egdcabf bgf bfgea
fgeab ca afcebg bdacfeg cfaedg gcfdb baec bfadeg bafgc acf | gebdcfa ecba ca fadegcb
dbcfg fgd bdegcaf fgec aegbdf ecdfab fbedc dacgb gdcebf gf | cefg dcbef fcge gbcadfe
bdfegc cbegaf gecbf dfcage bdacg ed bedf ced adcbefg gebcd | ed bcgafe cdgba cbgef
egadfb cdbfeg cegd fecab cgb gbdefca cg fgcdab egfdb bfceg | gbdfcae bgc cg cgb
gcafb gcf dcaebfg ecagb gf abcdeg gaef cafbge fdbac fegbdc | fgae cfgab fg bagce
"""
Puzzle Input
Paste your own input from Advent of Code or copy from sdball 2021 Advent of Code Day 8 input
puzzle_input = Kino.Input.textarea("Please paste your puzzle input for Day 8:")
puzzle_input =
puzzle_input
|> Kino.Input.read()
|> String.split("\n")
Part 1 - Test Input
test_input
|> String.split("\n", trim: true)
|> Enum.map(fn line ->
String.split(line, " | ")
|> Enum.at(1)
|> String.split()
|> Enum.map(&String.to_charlist/1)
|> Enum.filter(fn readout -> length(readout) in [2, 3, 4, 7] end)
|> Enum.count()
end)
|> Enum.sum()
Part 1 - Puzzle Input
puzzle_input
|> Enum.map(fn line ->
String.split(line, " | ")
|> Enum.at(1)
|> String.split()
|> Enum.map(&String.to_charlist/1)
|> Enum.filter(fn readout -> length(readout) in [2, 3, 4, 7] end)
|> Enum.count()
end)
|> Enum.sum()
Part 2
typical = %{
'abcefg' => 0,
'cf' => 1,
'acdeg' => 2,
'acdfg' => 3,
'bcdf' => 4,
'abdfg' => 5,
'abdefg' => 6,
'acf' => 7,
'abcdegf' => 8,
'abcdfg' => 9
}
test_input =
"acedgfb cdfbe gcdfa fbcad dab cefabd cdfgeb eafb cagedb ab | cdfeb fcadb cdfeb cdbaf"
[digits, readout] = test_input |> String.split([" | ", "\n"], trim: true)
IO.inspect(digits, label: :digits)
IO.inspect(readout, label: :readout)
translation = %{
?d => 'a',
?e => 'b',
?a => 'c',
?f => 'd',
?b => 'f',
?\s => ' '
}
digits
|> IO.inspect()
|> String.to_charlist()
|> Enum.map(fn c ->
translation[c] || "_"
end)
|> Enum.join("")
'dab' -- 'ab'
'fbcad' -- 'dab'
digits =
digits
|> String.split()
|> Enum.map(&to_charlist/1)
one = Enum.find(digits, fn readout -> length(readout) == 2 end)
four = Enum.find(digits, fn readout -> length(readout) == 4 end)
seven = Enum.find(digits, fn readout -> length(readout) == 3 end)
eight = Enum.find(digits, fn readout -> length(readout) == 7 end)
# with 1 4 7 8 solved then 9 is the only number left that masks 4
nine =
Enum.reject(digits, fn readout -> readout in [one, four, seven, eight] end)
|> Enum.find(fn readout -> four -- readout == [] end)
two =
Enum.reject(digits, fn readout -> readout in [one, four, seven, eight, nine] end)
|> Enum.find(fn readout -> length(four -- readout) == 2 end)
three =
Enum.reject(digits, fn readout -> readout in [one, two, four, seven, eight, nine] end)
|> Enum.find(fn readout -> length(readout -- two) == 1 end)
five =
Enum.reject(digits, fn readout -> readout in [one, two, three, four, seven, eight, nine] end)
|> Enum.find(fn readout -> length(readout -- three) == 1 end)
zero =
Enum.reject(digits, fn readout ->
readout in [one, two, three, four, five, seven, eight, nine]
end)
|> Enum.find(fn readout -> length(readout -- seven) == 3 end)
[six] =
Enum.reject(digits, fn readout ->
readout in [zero, one, two, three, four, five, seven, eight, nine]
end)
{zero, one, two, three, four, five, six, seven, eight, nine}
defmodule Unscrambler do
def unscramble(digits) do
digits =
digits
|> String.split()
|> Enum.map(&to_charlist/1)
one = Enum.find(digits, fn readout -> length(readout) == 2 end)
four = Enum.find(digits, fn readout -> length(readout) == 4 end)
seven = Enum.find(digits, fn readout -> length(readout) == 3 end)
eight = Enum.find(digits, fn readout -> length(readout) == 7 end)
# with 1 4 7 8 solved then 9 is the only number left that masks 4
nine =
Enum.reject(digits, fn readout -> readout in [one, four, seven, eight] end)
|> Enum.find(fn readout -> four -- readout == [] end)
two =
Enum.reject(digits, fn readout -> readout in [one, four, seven, eight, nine] end)
|> Enum.find(fn readout -> length(four -- readout) == 2 end)
three =
Enum.reject(digits, fn readout -> readout in [one, two, four, seven, eight, nine] end)
|> Enum.find(fn readout -> length(readout -- two) == 1 end)
five =
Enum.reject(digits, fn readout -> readout in [one, two, three, four, seven, eight, nine] end)
|> Enum.find(fn readout -> length(readout -- three) == 1 end)
zero =
Enum.reject(digits, fn readout ->
readout in [one, two, three, four, five, seven, eight, nine]
end)
|> Enum.find(fn readout -> length(readout -- seven) == 3 end)
[six] =
Enum.reject(digits, fn readout ->
readout in [zero, one, two, three, four, five, seven, eight, nine]
end)
{zero, one, two, three, four, five, six, seven, eight, nine}
|> Tuple.to_list()
|> Enum.map(&Enum.sort/1)
|> Enum.with_index()
|> Map.new()
end
end
[digits, reading] =
test_input
|> String.split([" | ", "\n"], trim: true)
translation = Unscrambler.unscramble(digits)
[digits, reading] =
test_input
|> String.split([" | ", "\n"], trim: true)
translation = Unscrambler.unscramble(digits)
reading
|> String.split()
|> Enum.map(&to_charlist/1)
|> Enum.map(fn number ->
number = Enum.sort(number)
translation[number]
end)
[digits, reading] =
"be cfbegad cbdgef fgaecd cgeb fdcge agebfd fecdb fabcd edb | fdgacbe cefdb cefbgd gcbe"
|> String.split([" | ", "\n"], trim: true)
translation = Unscrambler.unscramble(digits)
reading
|> String.split()
|> Enum.map(&to_charlist/1)
|> Enum.map(fn number ->
number = Enum.sort(number)
translation[number]
end)
[digits, reading] =
puzzle_input
|> Enum.at(0)
|> String.split(" | ")
translation = Unscrambler.unscramble(digits)
reading
|> String.split()
|> Enum.map(&to_charlist/1)
|> Enum.map(fn number ->
number = Enum.sort(number)
translation[number]
end)
puzzle_input
|> Enum.map(&String.split(&1, " | "))
|> Enum.map(fn [digits, reading] ->
translation = Unscrambler.unscramble(digits)
reading
|> String.split()
|> Enum.map(&to_charlist/1)
|> Enum.map(fn number ->
number = Enum.sort(number)
translation[number]
end)
|> Integer.undigits()
end)
|> Enum.sum()