diff options
Diffstat (limited to 'day15.lisp')
-rw-r--r-- | day15.lisp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/day15.lisp b/day15.lisp new file mode 100644 index 0000000..a27ff7d --- /dev/null +++ b/day15.lisp @@ -0,0 +1,48 @@ +(defun split-by-char (char string) + (loop for i = 0 then (1+ j) + as j = (position char string :start i) + collect (subseq string i j) + while j)) + +(defun read-seq (filespec) + (with-open-file (stream filespec) + (split-by-char #\, (read-line stream)))) + +(defun hash-algorithm (str) + (let ((res 0)) + (loop for c across str do (setf res (mod (* 17 (+ res (char-code c))) 256))) res)) + +(defun solve1 (filespec) + (reduce #'+ (mapcar #'hash-algorithm (read-seq filespec)))) + +(defun solve2 (filespec) + (let ((seq (read-seq filespec)) + (boxes (make-array 256 :initial-element ()))) + (loop for str in seq + as symbp = (loop for c across str + for i from 0 + if (or (equal c #\-) (equal c #\=)) return i) + as symb = (aref str symbp) + as label = (subseq str 0 symbp) + as hash = (hash-algorithm label) + if (equal symb #\=) + do (let* ((value (parse-integer (subseq str (1+ symbp)))) + (box (aref boxes hash)) + (lmember (assoc label box :test 'equal))) + (if lmember (setf (cdr lmember) value) + (setf (aref boxes hash) (acons label value box)))) + else + do (setf (aref boxes hash) + (remove-if (lambda (a) (equal label (car a))) + (aref boxes hash) :count 1))) + (loop for box across boxes + for i from 1 + sum (loop for lens in (reverse box) + for j from 1 + sum (* i j (cdr lens)))))) + +(print (solve1 "data/15/example.txt")) ;; 1320 +(print (solve1 "data/15/input.txt")) ;; 516804 +(print (solve2 "data/15/example.txt")) ;; 145 +(print (solve2 "data/15/input.txt")) ;; 231844 + |