Advent of Code 2023 Day 2
Mix.install([
{:kino_aoc, "~> 0.1.5"}
])
Section
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2023", "2", System.fetch_env!("LB_AOC_SESSION"))
defmodule AoC2023.Day02 do
def part1(puzzle_input) do
puzzle_input
|> parse_input()
|> Stream.filter(fn {_id, sets} ->
Enum.all?(sets, fn set ->
Map.get(set, "red", 0) <= 12 and
Map.get(set, "green", 0) <= 13 and
Map.get(set, "blue", 0) <= 14
end)
end)
|> Stream.map(&elem(&1, 0))
|> Enum.sum()
end
def part2(puzzle_input) do
puzzle_input
|> parse_input()
|> Stream.map(fn {_id, sets} ->
Enum.reduce(sets, %{}, fn set, acc ->
Map.merge(acc, set, fn _k, v1, v2 -> max(v1, v2) end)
end)
end)
|> Stream.map(&(&1["red"] * &1["green"] * &1["blue"]))
|> Enum.sum()
end
def parse_input(puzzle_input) do
puzzle_input
|> String.split("\n")
|> Enum.map(&parse_line/1)
end
defp parse_line(line) do
[id_part | sets_part] = String.split(line, ~r/[:;]/)
id =
~r/\d+/
|> Regex.run(id_part)
|> hd()
|> String.to_integer()
sets = Enum.map(sets_part, &parse_set/1)
{id, sets}
end
defp parse_set(string) do
~r/(\d+) (\w+)/
|> Regex.scan(string, capture: :all_but_first)
|> Map.new(fn [count, color] ->
{color, String.to_integer(count)}
end)
end
end
AoC2023.Day02.part1(puzzle_input)
AoC2023.Day02.part2(puzzle_input)