Advent 2021 - Day 3
Setup
Mix.install([
{:kino, github: "livebook-dev/kino"}
])
input = Kino.Input.textarea("Please paste your input file:")
input =
input
|> Kino.Input.read()
|> String.trim()
|> String.split("\n")
Part 1
epsilon =
input
|> Enum.reduce(nil, fn line, acc ->
result_of_line =
String.graphemes(line)
|> Enum.map(fn char ->
if char == "0" do
{1, 0}
else
{0, 1}
end
end)
if acc == nil do
result_of_line
else
Enum.zip(result_of_line, acc)
|> Enum.map(fn {r, a} ->
{r0, r1} = r
{a0, a1} = a
{r0 + a0, r1 + a1}
end)
end
end)
|> Enum.map(fn {zeros, ones} ->
if zeros > ones do
"0"
else
"1"
end
end)
{gamma, _} =
epsilon
|> Enum.map(fn value ->
if value == "1" do
"0"
else
"1"
end
end)
|> Enum.join()
|> Integer.parse(2)
{epsilon, _} =
epsilon
|> Enum.join()
|> Integer.parse(2)
epsilon * gamma
Part 2
defmodule Part2 do
def invoke(list, index, condition) do
if length(list) == 1 do
List.first(list)
else
%{"0" => zeros, "1" => ones} =
list
|> Enum.reduce(%{}, fn line, acc ->
char =
String.graphemes(line)
|> Enum.at(index)
Map.update(acc, char, 1, &(&1 + 1))
end)
keep = if condition.(zeros, ones), do: "0", else: "1"
list = Enum.filter(list, fn line -> String.graphemes(line) |> Enum.at(index) == keep end)
invoke(list, index + 1, condition)
end
end
end
oxygen_generator = Part2.invoke(input, 0, fn zeros, ones -> zeros > ones end)
c02_scrubber = Part2.invoke(input, 0, fn zeros, ones -> zeros <= ones end)
(Integer.parse(oxygen_generator, 2) |> elem(0)) * (Integer.parse(c02_scrubber, 2) |> elem(0))