diff options
-rwxr-xr-x | aoc/2022/07/part-one.janet | 58 | ||||
-rwxr-xr-x | aoc/2022/07/part-two.janet | 60 |
2 files changed, 118 insertions, 0 deletions
diff --git a/aoc/2022/07/part-one.janet b/aoc/2022/07/part-one.janet new file mode 100755 index 0000000..fba92e5 --- /dev/null +++ b/aoc/2022/07/part-one.janet @@ -0,0 +1,58 @@ +#!/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))))) + (print (+ (splice (filter (fn [n] + (<= n 100_000)) + (flatten (du fs))))))) diff --git a/aoc/2022/07/part-two.janet b/aoc/2022/07/part-two.janet new file mode 100755 index 0000000..36c25f1 --- /dev/null +++ b/aoc/2022/07/part-two.janet @@ -0,0 +1,60 @@ +#!/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)))))) |