changeset 11:e53d5f34cf17

Finish day 07
author Lewin Bormann <lbo@spheniscida.de>
date Sat, 10 Dec 2022 10:44:28 +0100
parents d110dc63f18e
children ecf80e49d919
files 07/07.jl
diffstat 1 files changed, 59 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/07/07.jl	Fri Dec 09 23:33:39 2022 +0100
+++ b/07/07.jl	Sat Dec 10 10:44:28 2022 +0100
@@ -107,7 +107,6 @@
             elseif state == "ls"
                 try
                     e = parse_one(line, ple)[1]::Entry;
-                    println(e, " -> ", current);
                     push!(current, e);
                     parsed = true;
                 catch exc
@@ -121,8 +120,65 @@
     root
 end
 
+function find_smallest_directory_larger_than(root::Entry, sz::Int)::Entry
+    best_dir = root;
+    best_difference = filesize(root) - sz;
+    for e in best_dir.children
+        if !isa(e, Dir)
+            continue;
+        end
+        fs = filesize(e);
+        if fs - sz >= 0 && fs - sz < best_difference
+            best_dir = e;
+            best_difference = fs - sz;
+        end
+
+        sub = find_smallest_directory_larger_than(e, sz);
+        fs = filesize(sub);
+        if fs - sz >= 0 && fs - sz < best_difference
+            best_dir = sub;
+            best_difference = fs - sz;
+        end
+    end
+    best_dir
+end
+
+function collect_all_dirs(root::Entry)::Vector{Entry}
+    queue = [root];
+    list = [root];
+    while length(queue) > 0
+        d = pop!(queue);
+        for e in d.children
+            if isa(e, Dir)
+                push!(queue, e)
+                push!(list, e);
+            end
+        end
+    end
+    list
+end
+
 open("07/input.txt"; read=true) do fh
     root = build_filesystem(fh);
-    println(root);
-    println(count_dirs_belowsize(root));
+    #println(root);
+    #println(count_dirs_belowsize(root));
+    #
+    total_size = filesize(root);
+    capacity = 70_000_000;
+    required_free = 30_000_000 - (capacity - total_size);
+    println("Using $total_size out of $capacity - need $required_free of additional free space");
+    sdlt = find_smallest_directory_larger_than(root, required_free);
+    println(sdlt.name, " ", filesize(sdlt));
+
+    # Serial algorithm:
+    by_filesize = [(d.name, filesize(d)) for d in collect_all_dirs(root)];
+    best = 1;
+    best_diff = by_filesize[1][2] - required_free;
+    for (i, (n, s)) in enumerate(by_filesize)
+        if (s-required_free) > 0 && (s-required_free) < best_diff
+            best = i;
+            best_diff = s - required_free;
+        end
+    end
+    println(by_filesize[best], " ", best_diff);
 end