(ql:quickload'(:fiveam:cl-ppcre))(defunparse-to-tree(stream)(labels((scan()(loopforitem=(read-linestreamnilnil)while(anditem(not(equal"$ cd .."item)))when(parseitem)collectit))(parse(item)(cond((ppcre:register-groups-bind(dir)("\\$ cd (\\w+|/)"item)(consdir(scan))))((ppcre:register-groups-bind((#'parse-integersize)name)("^(\\d+) ([.\\w]+)"item)(consnamesize))))))(car(scan))))(defunaggregate-size(tree)(let(dir-list)(labels((combiner(tri)(push(cons(cartri)(addertri))dir-list)(mapc(lambda(item)(unless(numberp(cdritem));; skips files(combineritem)))(cdrtri)))(adder(tri)(reduce(lambda(accitem)(+acc(if(numberp(cdritem))(cdritem)(adderitem))))(cdrtri):initial-value0)))(combinertree))dir-list))(defunflat-dir-size(filename)(with-open-file(infilename)(aggregate-size(parse-to-treein))))(defunaddr-small-dirs(dir-sizessmall-limit)(loopfor(_name.size)indir-sizeswhen(<sizesmall-limit)sumsize))(defundir-to-del(dir-sizestotal-diskneeded-disk)(let*((free-disk(-total-disk(cdar(lastdir-sizes))))(to-free(-needed-diskfree-disk)))(loopfor(_name.size)indir-sizeswhen(>sizeto-free)minimizingsize)))(fiveam:testresults(fiveam:is(=95437(addr-small-dirs(flat-dir-size"eg-in")100000)))(fiveam:is(=1845346(addr-small-dirs(flat-dir-size"input")100000)))(fiveam:is(=3636703(dir-to-del(flat-dir-size"input")7000000030000000))))