#!/usr/bin/env janet (def grammar ~{:filename (<- (some :S)) :dirname (+ (/ "/" :root) (/ ".." :parent) :filename) :cd (* "$ cd " (constant :cd) :dirname "\n") :file (* (<- :d+) " " (constant :name) :filename) :dir (* (constant :dir) "dir " (constant :name) :dirname) :ls (* "$ ls\n" (constant :ls) (group (any (/ (* (constant :stat) (+ :file :dir) "\n") ,struct)))) :main (some (/ (+ :cd :ls) ,tuple))}) (defn du [fs] (if (number? fs) [fs] (reduce (fn [[parent & children] [child & grandchildren]] [(+ parent child) (splice children) (if (empty? grandchildren) [] [child (splice grandchildren)])]) [0] (map du (values fs))))) (var path nil) (let [fs (table)] (each [cmd rest] (peg/match grammar (:read stdin :all)) (cond (= cmd :ls) (each {:name name :stat stat} rest (set ((array/peek path) name) (if (= stat :dir) (table) (scan-number stat)))) (= rest :root) (set path (array fs)) (= rest :parent) (array/pop path) (let [last (array/peek path)] (unless (last rest) (set (last rest) (table))) (array/push path (last rest))))) (let [usages (flatten (du fs))] (print (min (splice (filter (fn [n] (>= (+ n 40_000_000) (first usages))) usages))))))