import "aoc" for AoC class Entry { construct dir(parent) { _parent = parent _files = {} } construct file(parent, size) { _parent = parent _size = size } size { _size } files { _files } parent { _parent } total_size { if(_size) { return _size } else { return _files.map {|entry| entry.value.total_size}.reduce {|a, b| a+b} } } iter_dirs(fn) { if(_files) { fn.call(this) for(file in _files) { file.value.iter_dirs(fn) } } } } var lines = AoC.input.split("\n").where {|x| x != ""} var root = Entry.dir(null) var current = root for(line in lines) { if(line.startsWith("$ cd")) { var path = line.replace("$ cd ", "") if(path == "/") { current = root } else if(path == "..") { current = current.parent } else { current = current.files[path] } } else if(line == "$ ls") { // ignore } else if(line.startsWith("dir ")) { var path = line.replace("dir ", "") if(!current.files[path]) current.files[path] = Entry.dir(current) } else { var split = line.split(" ") var size = Num.fromString(split[0]) var path = split[1] if(!current.files[path]) current.files[path] = Entry.file(current, size) } } var sum_p1 = 0 var smallest_p2 = Num.infinity var to_free = 30000000 - (70000000 - root.total_size) root.iter_dirs {|dir| var size = dir.total_size if(size <= 100000) sum_p1 = sum_p1 + size if(size >= to_free && size <= smallest_p2) smallest_p2 = size } System.print(sum_p1) System.print(smallest_p2)