Advent 2022 - Day 5
Mix.install([
{:kino, github: "livebook-dev/kino"}
])
:ok
Setup
input = Kino.Input.textarea("Please paste your input file:")
[initial_state_string, instructions_string] =
input
|> Kino.Input.read()
|> String.split("\n\n", trim: true)
[" [D] \n[N] [C] \n[Z] [M] [P]\n 1 2 3 ",
"move 1 from 2 to 1\nmove 3 from 1 to 3\nmove 2 from 2 to 1\nmove 1 from 1 to 2"]
Parsing Initial State
rows =
initial_state_string
|> String.split("\n")
|> Enum.reverse()
|> tl()
|> Enum.reverse()
[" [D] ", "[N] [C] ", "[Z] [M] [P]"]
rows =
rows
|> Enum.map(fn line ->
line
|> String.graphemes()
|> tl
|> Enum.take_every(4)
end)
[[" ", "D", " "], ["N", "C", " "], ["Z", "M", "P"]]
initial_state =
rows
|> Enum.reduce(List.duplicate([], length(rows) + 1), fn row, acc ->
Enum.zip(row, acc)
|> Enum.map(fn {row, acc} -> [row | acc] end)
|> Enum.map(&Enum.filter(&1, fn item -> item != " " end))
end)
|> Enum.map(&Enum.reverse(&1))
[["N", "Z"], ["D", "C", "M"], ["P"]]
Parsing Instructions
instructions =
instructions_string
|> String.split("\n")
|> Enum.map(fn instruction ->
instruction
|> String.split(" ")
|> tl
|> Enum.take_every(2)
|> Enum.map(&String.to_integer(&1))
end)
[[1, 2, 1], [3, 1, 3], [2, 2, 1], [1, 1, 2]]
Utils
defmodule CargoCrane do
def activate(model, instructions, initial_state) do
Enum.reduce(instructions, initial_state, fn [move, from, to], state ->
to_move =
state
|> Enum.at(from - 1)
|> Enum.take(move)
state
|> List.update_at(to - 1, fn stack ->
case model do
:CrateMover9000 -> (to_move |> Enum.reverse()) ++ stack
:CrateMover9001 -> to_move ++ stack
_ -> raise "I don't know that model of crane!"
end
end)
|> List.update_at(from - 1, fn stack ->
stack |> Enum.drop(move)
end)
end)
end
def inspect_tops(state) do
state |> Enum.map(&hd(&1)) |> Enum.join()
end
end
{:module, CargoCrane, <<70, 79, 82, 49, 0, 0, 12, ...>>, {:inspect_tops, 1}}
Part 1
CargoCrane.activate(:CrateMover9000, instructions, initial_state)
|> CargoCrane.inspect_tops()
"CMZ"
Part 2
CargoCrane.activate(:CrateMover9001, instructions, initial_state)
|> CargoCrane.inspect_tops()
"MCD"