Advent of Code 2015 Day 15 Part 2
Mix.install([
{:kino_aoc, "~> 0.1"},
{:nx, "~> 0.9.2"}
])
Get Inputs
{:ok, puzzle_input} =
KinoAOC.download_puzzle("2015", "15", System.fetch_env!("LB_SESSION"))
My answer
get_ingredients_tensor = fn rows ->
rows
|> Enum.map(fn row ->
Regex.named_captures(
~r/(?[a-zA-Z]+): .+ (?\-*\d+), .+ (?\-*\d+), .+ (?\-*\d+), .+ (?\-*\d+), .+ (?\-*\d+)/,
row
)
|> then(fn %{"capacity" => capacity, "durability" => durability, "flavor" => flavor, "texture" => texture, "calories" => calories} ->
[
String.to_integer(capacity),
String.to_integer(durability),
String.to_integer(flavor),
String.to_integer(texture),
String.to_integer(calories)
]
end)
end)
|> Nx.tensor()
end
{ingredients, calories} =
puzzle_input
|> String.split("\n")
|> get_ingredients_tensor.()
|> Nx.split(4, axis: 1)
all_combinations =
for sprinkles <- 0..100,
peanut_butter <- 0..100,
frosting <- 0..100,
sugar <- 0..100,
sprinkles + peanut_butter + frosting + sugar == 100 do
[sprinkles, peanut_butter, frosting, sugar]
end
all_products =
all_combinations
|> Nx.tensor()
|> Nx.dot(ingredients)
|> Nx.max(0)
|> Nx.product(axes: [1], keep_axes: true)
valid_calories =
all_combinations
|> Nx.tensor()
|> Nx.dot(calories)
|> Nx.equal(500)
Nx.concatenate([all_products, valid_calories], axis: 1)
|> Nx.product(axes: [1])
|> Nx.reduce_max()