Advent 2021 - Day 8
Setup
Mix.install([
{:kino, github: "livebook-dev/kino"}
])
input = Kino.Input.textarea("Please paste your input file:")
parsed =
input
|> Kino.Input.read()
|> String.trim()
|> String.split("\n")
|> Enum.map(fn line ->
line |> String.split(" | ") |> Enum.map(&String.split(&1, " "))
end)
Utils
defmodule Utils do
def string_to_mapset(string) do
string
|> String.graphemes()
|> MapSet.new()
end
end
Part 1
parsed
|> Enum.map(fn [_ | output] -> output end)
|> List.flatten()
|> Enum.count(fn string ->
len = String.length(string)
len == 2 or len == 4 or len == 3 or len == 7
end)
Part 2
This part 2 had me pretty stumped…
Used some pointers from https://github.com/nint8835/AdventOfCode2021/blob/main/Day8/Day8.fsx in the production of this solution, thanks Riley!
all_outputs =
for [input, output] <- parsed do
everything = [input | output] |> List.flatten()
known_digits = %{
1 => everything |> Enum.find(&(String.length(&1) == 2)) |> Utils.string_to_mapset(),
4 => everything |> Enum.find(&(String.length(&1) == 4)) |> Utils.string_to_mapset(),
7 => everything |> Enum.find(&(String.length(&1) == 3)) |> Utils.string_to_mapset(),
8 => everything |> Enum.find(&(String.length(&1) == 7)) |> Utils.string_to_mapset()
}
intersection_check = [known_digits[1], known_digits[4], known_digits[7], known_digits[8]]
scrambled_to_value =
everything
|> Enum.map(fn value ->
set = Utils.string_to_mapset(value)
intersections =
Enum.map(intersection_check, fn check ->
MapSet.intersection(check, set) |> Enum.count()
end)
|> List.to_tuple()
case intersections do
{2, 2, 2, 2} -> {set, 1}
{1, 2, 2, 5} -> {set, 2}
{2, 3, 3, 5} -> {set, 3}
{2, 4, 2, 4} -> {set, 4}
{1, 3, 2, 5} -> {set, 5}
{1, 3, 2, 6} -> {set, 6}
{2, 2, 3, 3} -> {set, 7}
{2, 4, 3, 7} -> {set, 8}
{2, 4, 3, 6} -> {set, 9}
{2, 3, 3, 6} -> {set, 0}
_ -> nil
end
end)
|> Map.new()
output
|> Enum.map(fn value ->
Map.get(scrambled_to_value, Utils.string_to_mapset(value))
|> Integer.to_string()
end)
|> Enum.join("")
|> String.to_integer()
end
Enum.sum(all_outputs)