Powered by AppSignal & Oban Pro

🎄 Year 2022 🔔 Day 05

elixir/notebooks/2022/day05.livemd

🎄 Year 2022 🔔 Day 05

Parse input

filename = "#{__DIR__}/../../../inputs/2022/day05.txt"

[stack_input, [""], step_input] =
  File.stream!(filename)
  |> Enum.map(&String.trim(&1, "\n"))
  |> Enum.chunk_by(&(&1 == ""))

stacks =
  stack_input
  |> Enum.reverse()
  |> Enum.drop(1)
  |> Enum.map(&String.graphemes/1)
  |> Enum.map(&Enum.chunk_every(&1, 3, 4, :discard))
  |> Enum.map(&Enum.map(&1, fn [_, char, _] -> char end))
  |> then(fn rows ->
    rows |> List.zip() |> Enum.map(&Tuple.to_list/1) |> Enum.map(&Enum.reverse/1)
  end)
  |> Enum.map(&Enum.filter(&1, fn e -> e != " " end))

steps =
  step_input
  |> Enum.map(&String.split(&1, " "))
  |> Enum.map(&Enum.drop_every(&1, 2))
  |> Enum.map(&Enum.map(&1, fn e -> String.to_integer(e) end))

Part One

steps
|> Enum.reduce(stacks, fn [count, from, to], stacks ->
  to_add = Enum.at(stacks, from - 1) |> Enum.take(count) |> Enum.reverse()

  stacks
  |> List.update_at(from - 1, &Enum.drop(&1, count))
  |> List.update_at(to - 1, &Enum.concat(to_add, &1))
end)
|> Enum.map(&List.first/1)
|> Enum.join()

Part two

steps
|> Enum.reduce(stacks, fn [count, from, to], stacks ->
  to_add = Enum.at(stacks, from - 1) |> Enum.take(count)

  stacks
  |> List.update_at(from - 1, &Enum.drop(&1, count))
  |> List.update_at(to - 1, &Enum.concat(to_add, &1))
end)
|> Enum.map(&List.first/1)
|> Enum.join()