Powered by AppSignal & Oban Pro
Would you like to see your link here? Contact us

Advent of Code 2015 Day 15 Part 2

2015_day15_part2.livemd

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()