Powered by AppSignal & Oban Pro

Day 5: Supply Stacks

2022/day_05.livemd

Day 5: Supply Stacks

Mix.install([:kino])

input = Kino.Input.textarea("Please paste your input:")

Part 1

Run in Livebook

https://adventofcode.com/2022/day/5

[crate_inputs, procedure_inputs] =
  input
  |> Kino.Input.read()
  |> String.split("\n\n")

decode_crate = fn
  <<_::binary-size(1), crate::binary-size(1), _::binary-size(2)>> <> rest, fun ->
    [crate | fun.(rest, fun)]

  <<_::binary-size(1), crate::binary-size(1), _::binary-size(1)>>, _fun ->
    [crate]
end

crates =
  crate_inputs
  |> String.split("\n")
  |> Enum.drop(-1)
  |> Enum.map(fn crate_input ->
    decode_crate.(crate_input, decode_crate)
  end)
  |> Enum.zip_with(fn list -> list |> Enum.reject(&(&1 == " ")) end)
  |> IO.inspect()

decode_procedure = fn procedure_input ->
  Regex.named_captures(~r/move (?<count>\d+) from (?<from>\d+) to (?<to>\d+)/, procedure_input)
  |> Map.new(fn {key, value} -> {key, value |> String.to_integer()} end)
end

procedures =
  procedure_inputs
  |> String.split("\n", trim: true)
  |> Enum.map(fn procedure_input ->
    decode_procedure.(procedure_input)
  end)

_answer1 =
  procedures
  |> Enum.reduce(crates, fn %{"count" => count, "from" => from, "to" => to}, crates ->
    from = from - 1
    to = to - 1

    {move, new_from_list} = Enum.at(crates, from) |> Enum.split(count)
    new_to_list = Enum.reverse(move) ++ Enum.at(crates, to)

    crates
    |> List.replace_at(from, new_from_list)
    |> List.replace_at(to, new_to_list)
  end)
  |> Enum.map(&(&1 |> List.first()))
  |> Enum.join()

Part 2

https://adventofcode.com/2022/day/5#part2

_answer2 =
  procedures
  |> Enum.reduce(crates, fn %{"count" => count, "from" => from, "to" => to}, crates ->
    from = from - 1
    to = to - 1

    {move, new_from_list} = Enum.at(crates, from) |> Enum.split(count)
    new_to_list = move ++ Enum.at(crates, to)

    crates
    |> List.replace_at(from, new_from_list)
    |> List.replace_at(to, new_to_list)
  end)
  |> Enum.map(&(&1 |> List.first()))
  |> Enum.join()