about summary refs log tree commit diff
diff options
context:
space:
mode:
-rwxr-xr-xaoc/2022/07/part-one.janet58
-rwxr-xr-xaoc/2022/07/part-two.janet60
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))))))