-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathday_03.ex
53 lines (43 loc) · 1.46 KB
/
day_03.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
defmodule AdventOfCode.Y2022.Day03 do
@moduledoc """
--- Day 3: Rucksack Reorganization ---
Problem Link: https://adventofcode.com/2022/day/3
Difficulty: xs
Tags: set
"""
alias AdventOfCode.Helpers.{InputReader, Transformers}
def input, do: InputReader.read_from_file(2022, 3)
def run(input \\ input()) do
rucksacks = Transformers.lines(input)
{total_priority(compartment_priorities(rucksacks)),
total_priority(group_priorities(rucksacks))}
end
defp compartment_priorities(rucksacks),
do: Enum.map(rucksacks, &in_both_compartments/1)
defp group_priorities(rucksacks) do
rucksacks
|> Enum.chunk_every(3)
|> Enum.map(fn [x | xs] ->
Enum.reduce(xs, as_set(x), &MapSet.intersection(as_set(&1), &2))
end)
end
defp in_both_compartments(rucksack) do
mid = rucksack |> String.length() |> div(2)
[String.slice(rucksack, 0, mid), String.slice(rucksack, mid, mid)]
|> Enum.map(&MapSet.new(String.codepoints(&1)))
|> then(fn [a, b] -> MapSet.intersection(a, b) end)
end
defp as_set(rucksack), do: MapSet.new(String.codepoints(rucksack))
defp priority(char) do
case :binary.first(char) do
lower when lower >= ?a and lower <= ?z -> lower - ?a + 1
upper when upper >= ?A and upper <= ?Z -> upper - ?A + 27
end
end
defp total_priority(common_items) do
Enum.reduce(common_items, 0, fn x, acc ->
[common_item] = MapSet.to_list(x)
acc + priority(common_item)
end)
end
end