Day 15: Lens Library – Advent of Code 2023
input =
File.read!("/Users/pw/src/weiland/adventofcode/2023/input/15.txt")
|> String.trim()
|> String.split(",")
test_input = "rn=1,cm-,qp=3,cm=2,qp-,pc=4,ot=9,ab=5,pc-,pc=6,ot=7" |> String.split(",")
Parsing
Part One
hash = fn string ->
String.to_charlist(string) |> Enum.reduce(0, &rem((&1 + &2) * 17, 256))
end
hash.("HASH") == 52
part_one = fn input ->
input
|> Enum.map(&hash.(&1))
|> Enum.sum()
end
part_one.(test_input) == 1320 &&
part_one.(input)
Part Two
# unused now
parse_two = fn input ->
input
|> Enum.map(fn line ->
[label, flen] = String.split(line, ~r/[-=]/)
if flen != "" do
{:add, hash.(label), label, String.to_integer(flen)}
else
{:remove, hash.(label), label}
end
end)
end
parse_two.(test_input)
part_two = fn input ->
input
|> Enum.reduce(Map.new(), fn line, map ->
[label, flen] = String.split(line, ~r/[-=]/)
box = hash.(label)
lst = Map.get(map, box, [])
if flen == "" do
Map.put(map, box, Enum.reject(lst, fn {l, _i} -> l == label end))
else
flen = String.to_integer(flen)
updated =
if Enum.find(lst, fn {l, _i} -> l == label end),
do: Enum.map(lst, fn {l, i} -> if l == label, do: {l, flen}, else: {l, i} end),
else: lst ++ [{label, flen}]
Map.put(map, box, updated)
end
end)
|> Enum.map(fn {box, lst} ->
Enum.with_index(lst, fn {_l, focal_length}, i ->
(box + 1) * (i + 1) * focal_length
end)
|> Enum.sum()
end)
|> Enum.sum()
end
part_two.(test_input) == 145 &&
part_two.(input)