No Space Left On Device
Mix.install([{:kino, "~> 0.7.0"}])
Input
input = Kino.Input.textarea("Input:")
input = Kino.Input.read(input) |> String.trim() |> String.split("\n")
defmodule M do
def walk(input) do
{_, sizes} =
Enum.reduce(input, {["/"], %{}}, fn
_line = "$ cd /", _acc = {_pwd, sizes} ->
{["/"], sizes}
_line = "$ cd ..", _acc = {_pwd = [_ | up], sizes} ->
{up, sizes}
_line = "$ cd " <> rel, _acc = {pwd, sizes} ->
{[rel | pwd], sizes}
_line = "$ ls", acc ->
acc
_line = "dir " <> _, acc ->
acc
_line = file, _acc = {pwd, sizes} ->
[size, _name] = String.split(file, " ")
size = String.to_integer(size)
sizes = account(pwd, size, sizes)
{pwd, sizes}
end)
sizes
end
defp account(dir = [_ | parent], size, sizes) do
sizes = Map.update(sizes, dir, size, fn s -> s + size end)
account(parent, size, sizes)
end
defp account([], _size, sizes) do
sizes
end
end
sizes = M.walk(input)
sizes
|> Enum.filter(fn {_, size} -> size <= 100_000 end)
|> Enum.map(fn {_, size} -> size end)
|> Enum.sum()
used = Map.get(sizes, ["/"])
total = 70_000_000
required = 30_000_000
free = total - used
to_free = required - free
# Find the smallest directory that is larger than 'to_free':
Enum.map(sizes, fn {_dir, size} -> size end)
|> Enum.sort(:asc)
|> Enum.find(fn size -> size >= to_free end)