diff --git a/README.org b/README.org index 71d401c..c051b81 100644 --- a/README.org +++ b/README.org @@ -16,4 +16,6 @@ Day 5: [[https://livebook.dev/run?url=https%3A%2F%2Fgit.datarift.nl%2Ferwin%2Fao Day 6: [[https://livebook.dev/run?url=https%3A%2F%2Fgit.datarift.nl%2Ferwin%2Faoc2022%2Fraw%2Fbranch%2Fmain%2Fday6.livemd][Run in Livebook]] +Day 7: [[https://livebook.dev/run?url=https%3A%2F%2Fgit.datarift.nl%2Ferwin%2Faoc2022%2Fraw%2Fbranch%2Fmain%2Fday7.livemd][Run in Livebook]] + diff --git a/day7.livemd b/day7.livemd new file mode 100644 index 0000000..7dc729c --- /dev/null +++ b/day7.livemd @@ -0,0 +1,132 @@ +# AOC 2022 - Day 7 + +```elixir +Mix.install([ + {:req, "~> 0.3.3"} +]) +``` + +## Puzzle description + +[Day 7: No Space Left On Device](https://adventofcode.com/2022/day/7). + +## Input + +```elixir +defmodule Load do + def input do + aoc_session = System.fetch_env!("LB_AOC_SESSION") + input_url = "https://adventofcode.com/2022/day/7/input" + Req.get!(input_url, headers: [cookie: "session=#{aoc_session}"]).body + end +end +``` + +## Solution + +```elixir +defmodule Util do + def all_dir_sizes(input) do + input + |> String.split("\n", trim: true) + |> Stream.reject(&(&1 == "$ ls" || match?("dir " <> _, &1))) + |> Stream.concat(Stream.repeatedly(fn -> "$ cd .." end)) + |> Stream.transform( + # initial accumulator + [0], + + # reducer + fn + "$ cd ..", [_last] -> + {:halt, nil} + + "$ cd ..", [leaving_size, parent_size | stack] -> + {[leaving_size], [parent_size + leaving_size | stack]} + + "$ cd " <> _, stack -> + {[], [0 | stack]} + + file, [size | stack] -> + [filesize, _] = String.split(file, " ") + {[], [size + String.to_integer(filesize) | stack]} + end + ) + |> Enum.to_list() + |> Enum.reverse() + end +end +``` + +```elixir +defmodule Part1 do + def run(input) do + input + |> Util.all_dir_sizes() + |> Enum.reject(&(&1 > 100_000)) + |> Enum.sum() + end +end + +defmodule Part2 do + def run(input) do + dir_sizes = Util.all_dir_sizes(input) + needed_space = 30_000_000 + hd(dir_sizes) - 70_000_000 + + dir_sizes + |> Enum.filter(&(&1 > needed_space)) + |> Enum.min() + end +end + +ExUnit.start(autorun: false) + +defmodule Test do + use ExUnit.Case, async: true + @example_input ~s($ 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) + @input Load.input() + + test "it loads the input" do + assert String.length(@input) > 0 + end + + test "part 1 example" do + assert Part1.run(@example_input) === 95437 + end + + test "part 1" do + assert Part1.run(@input) === 919_137 + end + + test "part 2 example" do + assert Part2.run(@example_input) === 24_933_642 + end + + test "part 2" do + assert Part2.run(@input) === 2_877_389 + end +end + +ExUnit.run() +```