Day 2: Cube Conundrum
Mix.install([
{:kino, "~> 0.11.3"}
])
Input
input = Kino.Input.textarea("input")
Part 1
defmodule Parser do
def parse_games(games) do
games
|> String.split("\n")
|> Enum.map(&parse_game/1)
end
def parse_game(game) do
["Game " <> game_id, sets] = String.split(game, ": ")
parsed =
sets
|> String.split("; ")
|> Enum.map(fn set ->
set
|> String.split(", ")
|> Enum.map(fn s ->
[num, color] = String.split(s, " ")
{String.to_integer(num), color}
end)
end)
{String.to_integer(game_id), parsed}
end
end
defmodule Part1 do
@color_cubes %{
"red" => 12,
"green" => 13,
"blue" => 14
}
def possible_ids(games) do
games
|> Enum.filter(fn {_game_id, game} -> possible?(game) end)
|> Enum.map(fn {game_id, _game} -> game_id end)
end
def possible?(game) do
game
|> Enum.concat()
|> Enum.map(fn {num, color} -> num <= @color_cubes[color] end)
|> Enum.all?()
end
end
input
|> Kino.Input.read()
|> Parser.parse_games()
|> Part1.possible_ids()
|> Enum.sum()
Part 2
defmodule Part2 do
def power_of_games(games) do
games
|> Enum.map(fn {_, game} -> power_of_game(game) end)
|> Enum.sum()
end
def power_of_game(game) do
game
|> Enum.concat()
|> Enum.group_by(fn {_num, color} -> color end)
|> Enum.map(fn {_color, cubes} ->
cubes
|> Enum.map(fn {num, _} -> num end)
|> Enum.max()
end)
|> Enum.reduce(&*/2)
end
end
input
|> Kino.Input.read()
|> Parser.parse_games()
|> Part2.power_of_games()