Day 15
Mix.install([
{:kino, "~> 0.11.0"}
])
Section
input = Kino.Input.textarea("Input", monospace: true)
defmodule HASH do
def box(label) do
for <>, reduce: 0 do
hash ->
rem(17 * (hash + c), 256)
end
end
end
defmodule HASHMAP do
def add(hashmap, label, focal_length) do
Map.update(
hashmap,
HASH.box(label),
Keyword.new([{String.to_atom(label), focal_length}]),
fn lenses ->
Keyword.update(lenses, String.to_atom(label), focal_length, fn _ -> focal_length end)
end
)
end
def remove(hashmap, label) do
Map.update(hashmap, HASH.box(label), Keyword.new(), fn lenses ->
Keyword.delete(lenses, String.to_atom(label))
end)
end
def power(hashmap) do
Enum.flat_map(hashmap, fn {box, lenses} ->
Enum.with_index(lenses, fn {_label, focal_length}, slot ->
(box + 1) * (slot + 1) * focal_length
end)
end)
|> Enum.sum()
end
end
input
|> Kino.Input.read()
|> String.splitter(",")
|> Stream.map(&HASH.box/1)
|> Enum.sum()
input
|> Kino.Input.read()
|> String.splitter(",")
|> Stream.map(fn str ->
case String.split(str, ["=", "-"], trim: true) do
[label] -> {:remove, [label]}
[label, focal_length] -> {:add, [label, String.to_integer(focal_length)]}
end
end)
|> Enum.reduce(%{}, fn {op, args}, map ->
apply(HASHMAP, op, [map | args])
end)
|> HASHMAP.power()