Day 3: Binary Diagnostic
Mix.install([:kino])
input = Kino.Input.textarea("Please paste your input:")
Setup
inputs =
input
|> Kino.Input.read()
|> String.split("\n", trim: true)
|> Enum.map(&String.split(&1, "", trim: true))
Part 1
https://adventofcode.com/2021/day/3
Solve: Part 1
separator = Enum.count(inputs) / 2
[gamma_rate, epsilon_rate] =
inputs
|> Enum.zip_with(& &1)
|> Enum.map(fn list ->
case Enum.count(list, &(&1 == "1")) > separator do
true -> ["1", "0"]
false -> ["0", "1"]
end
end)
|> Enum.zip_with(& &1)
|> Enum.map(fn list ->
list
|> Enum.join()
|> Integer.parse(2)
|> elem(0)
end)
_answer = gamma_rate * epsilon_rate
Part 2
https://adventofcode.com/2021/day/3#part2
Solve: Part 2
defmodule Part2.Solver do
def solve(inputs, mode) do
{result, _} =
inputs
|> do_solve(0, mode)
|> Enum.join()
|> Integer.parse(2)
result
end
def do_solve([report], _, _) do
report
end
def do_solve(reports, index, mode) do
grouped_reports =
reports
|> Enum.group_by(fn report ->
report |> Enum.at(index)
end)
reports0 = grouped_reports |> Map.get("0", [])
reports1 = grouped_reports |> Map.get("1", [])
op_compare =
case mode do
:oxygen_generator_rating -> &Kernel.>/2
:co2_scrubber_rating -> &Kernel.<=/2
end
filtered_reports =
case op_compare.(Enum.count(reports0), Enum.count(reports1)) do
true -> reports0
false -> reports1
end
do_solve(filtered_reports, index + 1, mode)
end
end
oxygen_generator_rating = Part2.Solver.solve(inputs, :oxygen_generator_rating)
co2_scrubber_rating = Part2.Solver.solve(inputs, :co2_scrubber_rating)
_answer = oxygen_generator_rating * co2_scrubber_rating