aboutsummaryrefslogtreecommitdiffstats
path: root/AoC2022/07/solver.lisp
diff options
context:
space:
mode:
authorOscar Najera <hi@oscarnajera.com>2022-12-08 15:32:43 +0100
committerOscar Najera <hi@oscarnajera.com>2022-12-08 15:32:43 +0100
commit23bbb7d957af6510479bce016f5ef7f8fdf6886e (patch)
treed0ce6b2ff5f4d154f4231e9db3080759a58a0141 /AoC2022/07/solver.lisp
parentc3cf19fc1ff67d89d69eb80e974bc330daebb202 (diff)
downloadscratch-23bbb7d957af6510479bce016f5ef7f8fdf6886e.tar.gz
scratch-23bbb7d957af6510479bce016f5ef7f8fdf6886e.tar.bz2
scratch-23bbb7d957af6510479bce016f5ef7f8fdf6886e.zip
[AoC2022] 07 CL
Diffstat (limited to 'AoC2022/07/solver.lisp')
-rw-r--r--AoC2022/07/solver.lisp65
1 files changed, 65 insertions, 0 deletions
diff --git a/AoC2022/07/solver.lisp b/AoC2022/07/solver.lisp
new file mode 100644
index 0000000..f0f5a93
--- /dev/null
+++ b/AoC2022/07/solver.lisp
@@ -0,0 +1,65 @@
+(ql:quickload '(:fiveam :cl-ppcre))
+
+(defun parse-to-tree (stream)
+ (labels ((scan ()
+ (loop for item = (read-line stream nil nil)
+ while (and item (not (equal "$ cd .." item)))
+ when (parse item) collect it))
+ (parse (item)
+ (cond
+ ((ppcre:register-groups-bind (dir) ("\\$ cd (\\w+|/)" item) (cons dir (scan))))
+ ((ppcre:register-groups-bind (size name) ("^(\\d+) (\\w+)" item)
+ (cons name (parse-integer size)))))))
+ (car (scan))))
+
+(defun aggregate-size (tree)
+ (labels ((combiner (tri)
+ (list (car tri)
+ (adder tri)
+ (reduce (lambda (acc item)
+ (if (numberp (cdr item)) ;; skips files
+ acc
+ (cons (combiner item) acc)))
+ (cdr tri) :initial-value nil)))
+ (adder (tri)
+ (reduce (lambda (acc item)
+ (+ acc (if (numberp (cdr item))
+ (cdr item)
+ (adder item))))
+ (cdr tri) :initial-value 0)))
+ (combiner tree)))
+
+(defun flat-dir-size ()
+ (with-open-file (in "input")
+ (delete nil
+ (flatten-tree
+ (aggregate-size
+ (parse-to-tree in)))
+ :test #'eq) ))
+
+(defun flatten-tree (tree)
+ (cond
+ ((null tree) nil)
+ ((consp (car tree)) (nconc (flatten-tree (car tree))
+ (flatten-tree (cdr tree))))
+ (t (cons (car tree) (flatten-tree (cdr tree))))))
+
+(defun addr-small-dirs (dir-sizes small-limit)
+ (loop for (_name size) on dir-sizes by #'cddr
+ when (< size small-limit)
+ sum size))
+
+(defun dir-to-del (dir-sizes total-disk needed-disk)
+ (let* ((free-disk (- total-disk (cadr dir-sizes)))
+ (to-free (- needed-disk free-disk)))
+ (loop for (_ size) on dir-sizes by #'cddr
+ when (> size to-free)
+ minimizing size)))
+
+(fiveam:test results
+ (fiveam:is (= 1845346
+ (addr-small-dirs (flat-dir-size) 100000)))
+ (fiveam:is (= 3636703
+ (dir-to-del (flat-dir-size) 70000000 30000000))))
+
+(fiveam:run-all-tests)