summaryrefslogtreecommitdiffstats
path: root/day15.lisp
diff options
context:
space:
mode:
Diffstat (limited to 'day15.lisp')
-rw-r--r--day15.lisp48
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
+