33 lines
960 B
Elixir
33 lines
960 B
Elixir
defmodule Aoc2023.Day15 do
|
|
use Aoc2023
|
|
|
|
def parse(input) do
|
|
input |> String.split(",")
|
|
end
|
|
|
|
defp hash(str) do
|
|
for <<char <- str>>, reduce: 0 do
|
|
acc -> Bitwise.band((acc + char) * 17, 255)
|
|
end
|
|
end
|
|
|
|
def part1(input) do
|
|
input |> Enum.map(&hash/1) |> Enum.sum
|
|
end
|
|
|
|
def part2(input) do
|
|
for instr <- input, reduce: 0..255 |> Enum.map(&{&1, []}) |> Enum.into(%{}) do
|
|
boxes ->
|
|
[_, label, op, lens] = Regex.run(~r/([a-z]+)([-=])(\d*)/, instr)
|
|
box = hash(label)
|
|
label = String.to_atom(label)
|
|
case op do
|
|
"=" -> boxes |> Map.update!(box, &Keyword.update(&1, label, String.to_integer(lens), fn _ -> String.to_integer(lens) end))
|
|
"-" -> boxes |> Map.update!(box, &Keyword.delete(&1, label))
|
|
end
|
|
end
|
|
|> Enum.flat_map(fn {box, lenses} -> lenses |> Enum.with_index(1) |> Enum.map(fn {{_, focus}, i} -> focus * (box + 1) * i end) end)
|
|
|> Enum.sum
|
|
end
|
|
end
|