commit - 3bdd47fe03b5fda0f595ec106a745a0a36795a3a
commit + b422a1c50fd4de5f2f29dee2e1ad6d62fc2d4915
blob - a22dfa9be0742d1d8e3f0ccb1d1abc287bda8fbb
blob + 15b1f164e63cb4968c09fced56153e1c5df867df
--- src/day-12.lisp
+++ src/day-12.lisp
(groups (read-number-list line :start (1+ space-pos))))
(values springs groups)))
-(defparameter *cache* (make-hash-table :test 'equal))
-
(defun possible-arrangements (springs groups)
- (labels ((next (springs groups current-group-length)
- (when (null springs)
- (when (if groups
- (and (= (length groups) 1)
- (= (car groups) current-group-length))
- (= current-group-length 0))
- (return-from next 1))
- (return-from next 0))
- (let ((current (car springs))
- (not-in-group (= current-group-length 0))
- (group-filled? (and groups
- (= (car groups) current-group-length)))
- (count 0))
- (when group-filled?
- (pop groups))
- (cond
- ((char= current #\.)
- (when (or not-in-group group-filled?)
- (incf count (next-cache (cdr springs) groups 0))))
- ((char= current #\#)
- (unless group-filled?
- (incf count (next-cache (cdr springs) groups (1+ current-group-length)))))
- ((char= current #\?)
- (when (or not-in-group group-filled?)
- (incf count (next-cache (cdr springs) groups 0)))
- (unless group-filled?
- (incf count (next-cache (cdr springs) groups (1+ current-group-length))))))
- count))
- (next-cache (&rest args)
- (or (gethash args *cache*)
- (setf (gethash args *cache*)
- (apply #'next args)))))
- (next-cache springs groups 0)))
+ (let ((cache (make-hash-table)))
+ (labels ((next (springs groups current-group-length)
+ (when (null springs)
+ (when (if groups
+ (and (= (length groups) 1)
+ (= (car groups) current-group-length))
+ (= current-group-length 0))
+ (return-from next 1))
+ (return-from next 0))
+ (let ((current (car springs))
+ (not-in-group (= current-group-length 0))
+ (group-filled? (and groups
+ (= (car groups) current-group-length)))
+ (count 0))
+ (when group-filled?
+ (pop groups))
+ (cond
+ ((char= current #\.)
+ (when (or not-in-group group-filled?)
+ (incf count (next-cache (cdr springs) groups 0))))
+ ((char= current #\#)
+ (unless group-filled?
+ (incf count (next-cache (cdr springs) groups (1+ current-group-length)))))
+ ((char= current #\?)
+ (when (or not-in-group group-filled?)
+ (incf count (next-cache (cdr springs) groups 0)))
+ (unless group-filled?
+ (incf count (next-cache (cdr springs) groups (1+ current-group-length))))))
+ count))
+ (next-cache (springs groups current-group-length)
+ (let ((key (logior (ash (length springs) 16)
+ (ash (length groups) 8)
+ current-group-length)))
+ (or (gethash key cache)
+ (setf (gethash key cache)
+ (next springs groups current-group-length))))))
+ (next-cache springs groups 0))))
(defun day-12 (input)
(loop with task-1 = 0