Powered by AppSignal & Oban Pro

Aoc 2022 day7

Day 7: No Space Left On Device.livemd

Aoc 2022 day7

Mix.install(
  [
    {:kino_aoc, git: "https://github.com/ljgago/kino_aoc"}
  ],
  force: true
)

inputs

sample_input = """
$ cd /
$ ls
dir a
14848514 b.txt
8504156 c.dat
dir d
$ cd a
$ ls
dir e
29116 f
2557 g
62596 h.lst
$ cd e
$ ls
584 i
$ cd ..
$ cd ..
$ cd d
$ ls
4060174 j
8033020 d.log
5626152 d.ext
7214296 k
"""
{:ok, input} = KinoAOC.download_puzzle("2022", "7", System.fetch_env!("LB_TAIANSU"))
defmodule Day7 do
  def run("$ cd /", {_routes, sizes}) do
    {["/"], sizes}
  end

  def run("$ cd ..", {[_hd | tail], sizes}) do
    {tail, sizes}
  end

  def run("$ cd " <> dir, {routes, sizes}) do
    {[dir | routes], sizes}
  end

  def run("dir " <> name, {routes, sizes}) do
    {
      routes,
      name
      |> sub_dir(routes)
      |> then(&amp;Map.put_new(sizes, &amp;1, 0))
    }
  end

  def run("$ ls", rs) do
    rs
  end

  def run(file, {routes, sizes}) do
    file_size = file |> String.split(" ") |> List.first() |> String.to_integer()

    {
      routes,
      routes
      |> Day7.scan_routes()
      |> Enum.reduce(sizes, fn dir, acc ->
        Map.update!(acc, dir, &amp;(&amp;1 + file_size))
      end)
    }
  end

  def scan_routes(routes) do
    routes
    |> Enum.reverse()
    |> Enum.scan(&amp;Path.join(&amp;2, &amp;1))
  end

  def sub_dir(dir, routes) do
    [dir | routes]
    |> Enum.reverse()
    |> Path.join()
  end
end

du

du =
  input
  |> String.split("\n", trim: true)
  |> Enum.reduce({[], %{"/" => 0}}, &amp;Day7.run/2)
  |> elem(1)
  |> IO.inspect(limit: :infinity)

part 1

du
|> Enum.map(&amp;elem(&amp;1, 1))
|> Enum.filter(&amp;(&amp;1 <= 100_000))
|> Enum.sum()

part2

unused_space = 70_000_000 - Map.get(du, "/")
required_space = 30_000_000 - unused_space

du
|> Enum.map(&amp;elem(&amp;1, 1))
|> Enum.filter(&amp;(&amp;1 >= required_space))
|> Enum.min()