Skip to content

Commit 89c929f

Browse files
committed
Add solution for Day 15 puzzle
1 parent bc8b58e commit 89c929f

File tree

2 files changed

+73
-0
lines changed

2 files changed

+73
-0
lines changed

15/sample_input

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7

15/sol.exs

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
defmodule Day15 do
2+
def read_input(file_path) do
3+
case File.read(file_path) do
4+
{:ok, content} ->
5+
content
6+
|> String.split(",", trim: true)
7+
8+
{:error, reason} ->
9+
raise "Oh no! #{reason}"
10+
end
11+
end
12+
13+
def partA(file_path) do
14+
file_path
15+
|> read_input()
16+
|> Enum.map(&hash/1)
17+
|> Enum.sum()
18+
end
19+
20+
def partB(file_path) do
21+
file_path
22+
|> read_input()
23+
|> Enum.reduce(Enum.take(Stream.cycle([[]]), 256), &apply_op(&2, extract_op(&1)))
24+
|> total_focusing_power()
25+
end
26+
27+
def hash(l), do: hash(String.to_charlist(l), 0)
28+
def hash([], acc), do: acc
29+
def hash([h | t], acc), do: hash(t, Integer.mod((acc + h) * 17, 256))
30+
31+
def extract_op(str) do
32+
case Regex.named_captures(~r/(?<label>\w+)((=(?<number>\d+))|-)/, str) do
33+
%{"label" => label, "number" => number} when number != "" ->
34+
{label, {:add, String.to_integer(number)}}
35+
36+
%{"label" => label} ->
37+
{label, {:remove}}
38+
end
39+
end
40+
41+
def remove(box, label), do: Enum.reject(box, fn {l, _} -> l == label end)
42+
43+
def add(box, label, value) do
44+
case Enum.find_index(box, fn {l, _} -> l == label end) do
45+
nil -> box ++ [{label, value}]
46+
idx -> List.replace_at(box, idx, {label, value})
47+
end
48+
end
49+
50+
def apply_op_to_box(box, label, {:add, value}), do: add(box, label, value)
51+
def apply_op_to_box(box, label, {:remove}), do: remove(box, label)
52+
53+
def apply_op(l, {label, op}) do
54+
Enum.at(l, hash(label))
55+
|> apply_op_to_box(label, op)
56+
|> (&List.replace_at(l, hash(label), &1)).()
57+
end
58+
59+
def total_focusing_power(boxes) do
60+
Enum.with_index(boxes)
61+
|> Enum.flat_map(fn {box, box_index} ->
62+
Enum.with_index(box)
63+
|> Enum.map(fn {{_, focal_length}, lens_index} ->
64+
(box_index + 1) * (lens_index + 1) * focal_length
65+
end)
66+
end)
67+
|> Enum.sum()
68+
end
69+
end
70+
71+
IO.puts(Day15.partA("./input"))
72+
IO.puts(Day15.partB("./input"))

0 commit comments

Comments
 (0)