advent_of_code/elixir/lib/Y2023/2023_day2.exs
2024-11-15 21:03:49 -05:00

61 lines
1.3 KiB
Elixir

red_limit = 12
green_limit = 13
blue_limit = 14
parse_rounds = fn s ->
s
|> String.split(";")
|> Enum.map(
&Enum.map(
String.split(&1, ","),
fn x ->
[_, count, color] = Regex.run(~r/(\d+) (.+)/, String.trim(x))
{count, _} = count |> Integer.parse()
color = color |> String.to_atom()
{color, count}
end
)
)
end
all_games =
for line <- IO.stream(),
line |> String.trim() |> String.length() > 0,
[_, id, rounds] = Regex.run(~r/Game (\d+): (.+)/, line) do
{id |> Integer.parse() |> elem(0), parse_rounds.(rounds)}
end
part1 = fn games ->
games
|> Enum.filter(fn {_, games} ->
Enum.all?(games, fn game ->
game |> Keyword.get(:green, 0) <= green_limit &&
game |> Keyword.get(:red, 0) <= red_limit &&
game |> Keyword.get(:blue, 0) <= blue_limit
end)
end)
|> Enum.map(&elem(&1, 0))
|> Enum.sum()
end
part2 = fn games ->
games
|> Enum.map(
&(elem(&1, 1)
|> Enum.reduce(
{0, 0, 0},
fn round, {red, green, blue} ->
{
max(red, Keyword.get(round, :red, 0)),
max(green, Keyword.get(round, :green, 0)),
max(blue, Keyword.get(round, :blue, 0))
}
end
))
)
|> Enum.map(fn {x, y, z} -> x * y * z end)
|> Enum.sum()
end
part2.(all_games) |> IO.puts()