83 lines
1.7 KiB
Elixir
83 lines
1.7 KiB
Elixir
|
|
defmodule Aoc.Solution.Day03 do
|
||
|
|
import Aoc.Utils
|
||
|
|
|
||
|
|
@name "Day 3: Rucksack Reorganization"
|
||
|
|
@behaviour Solution
|
||
|
|
|
||
|
|
@impl Solution
|
||
|
|
def get_name, do: @name
|
||
|
|
|
||
|
|
@impl Solution
|
||
|
|
def present(solution), do: "Sum of priorities is #{solution}"
|
||
|
|
|
||
|
|
@impl Solution
|
||
|
|
def present_again(solution), do: "Sum of the unauthenticated priorities are #{solution}"
|
||
|
|
|
||
|
|
@impl Solution
|
||
|
|
def parse!(raw) do
|
||
|
|
raw
|
||
|
|
|> split_lines()
|
||
|
|
end
|
||
|
|
|
||
|
|
@impl Solution
|
||
|
|
def solve(rucksacks) do
|
||
|
|
rucksacks
|
||
|
|
|> Enum.map(&compartment_pair/1)
|
||
|
|
|> Enum.map(&calculate_compartment_priorities/1)
|
||
|
|
|> Enum.sum()
|
||
|
|
end
|
||
|
|
|
||
|
|
@impl Solution
|
||
|
|
def solve_again(rucksacks) do
|
||
|
|
rucksacks
|
||
|
|
|> Enum.chunk_every(3)
|
||
|
|
|> Enum.map(&calculate_compartment_priorities/1)
|
||
|
|
|> Enum.sum()
|
||
|
|
end
|
||
|
|
|
||
|
|
def compartment_pair(line) do
|
||
|
|
half = line |> String.length() |> div(2)
|
||
|
|
String.split_at(line, half)
|
||
|
|
end
|
||
|
|
|
||
|
|
def calculate_compartment_priorities(compartments) when is_tuple(compartments) do
|
||
|
|
[a, b] =
|
||
|
|
compartments
|
||
|
|
|> Tuple.to_list()
|
||
|
|
|> Enum.map(&distinct/1)
|
||
|
|
|
||
|
|
common_priority(a, b)
|
||
|
|
end
|
||
|
|
|
||
|
|
def calculate_compartment_priorities(compartments) do
|
||
|
|
[a, b, c] =
|
||
|
|
compartments
|
||
|
|
|> Enum.map(&distinct/1)
|
||
|
|
|
||
|
|
common_priority(a, b, c)
|
||
|
|
end
|
||
|
|
|
||
|
|
def distinct(line) do
|
||
|
|
line |> String.codepoints() |> MapSet.new()
|
||
|
|
end
|
||
|
|
|
||
|
|
def priority(char) when is_binary(char), do: char |> String.to_charlist() |> hd |> priority
|
||
|
|
def priority(n) when n > 96, do: n - 96
|
||
|
|
def priority(n), do: n - 38
|
||
|
|
|
||
|
|
def common_priority(a, b, c) do
|
||
|
|
MapSet.intersection(a, b)
|
||
|
|
|> MapSet.intersection(c)
|
||
|
|
|> MapSet.to_list()
|
||
|
|
|> List.first()
|
||
|
|
|> priority
|
||
|
|
end
|
||
|
|
|
||
|
|
def common_priority(a, b) do
|
||
|
|
MapSet.intersection(a, b)
|
||
|
|
|> MapSet.to_list()
|
||
|
|
|> List.first()
|
||
|
|
|> priority
|
||
|
|
end
|
||
|
|
end
|