Mercurial > lbo > hg > aoc22
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