diff options
-rw-r--r-- | AoC2023/day07/solver.lisp | 73 |
1 files changed, 52 insertions, 21 deletions
diff --git a/AoC2023/day07/solver.lisp b/AoC2023/day07/solver.lisp index 3a1fe8a..4cb0a9e 100644 --- a/AoC2023/day07/solver.lisp +++ b/AoC2023/day07/solver.lisp @@ -11,15 +11,23 @@ KK677 28 KTJJT 220 QQQJA 483") -(defun occurences (str) - (let ((bag (make-hash-table))) - (loop - for le across str - do (incf (gethash le bag 0))) - (sort (alexandria:hash-table-values bag) #'>))) +(defun occurences (str &optional joker) + (let* ((bag (make-hash-table)) + (jokers + (loop + for le across str + do (incf (gethash le bag 0)) + count (eq le #\J))) + (result (sort (alexandria:hash-table-values bag) #'>))) + (when joker + (setf result (remove jokers result :count 1)) + (if (= jokers 5) + (setf result '(5)) + (incf (car result) jokers))) + result)) -(defun hand-type (str) - (trivia:match (occurences str) +(defun hand-type (str &optional joker) + (trivia:match (occurences str joker) ((list 5) 5) ((list 4 1) 4) ((list 3 2) 3) @@ -28,27 +36,38 @@ QQQJA 483") ((list 2 1 1 1) 0) ((list 1 1 1 1 1) -1))) -(defun card-strength (card) - (position card "23456789TJQKA")) +(defun card-strength (card &optional joker) + (position card + (if joker + "J23456789TQKA" + "23456789TJQKA"))) -(defun card-< (a b) - (< (card-strength a) (card-strength b))) +(defun card-< (a b &optional joker) + (< (card-strength a joker) (card-strength b joker))) -(defun hand-< (a b) - (let ((a-t (hand-type a)) - (b-t (hand-type b))) +(defun hand-< (a b &optional joker) + (let ((a-t (hand-type a joker)) + (b-t (hand-type b joker))) (cond ((< a-t b-t)) ((= a-t b-t) (loop for l across a for s across b unless (eq l s) - return (card-< l s)))))) + return (card-< l s joker)))))) (f:test partial (f:is (equal '(3 1 1) (occurences "QJQAQ"))) + (f:is + (equal '(4 1) + (occurences "QJQAQ" 'joker))) + (f:is + (equal '(5) + (occurences "JJJJJ" 'joker))) + (f:is (card-< #\2 #\J)) + (f:is-false (card-< #\2 #\J 'joker)) (f:is (hand-< "2AAAA" "33332")) (f:is (hand-< "77788" "77888")) (f:is (hand-< "77788" "77778"))) @@ -65,16 +84,28 @@ QQQJA 483") for c from 1 sum (* c bid))) -(defun solver1 (lines) +(defun solver (lines &optional joker) (arrows:-> (parse-input lines) - (sort #'hand-< :key #'car) + (sort (lambda (a b) + (hand-< a b joker)) + :key #'car) (total-win))) + (f:test solutions (f:is (= 6440 - (solver1 eg-input))) + (solver eg-input))) + (f:is + (= 5905 + (solver eg-input 'joker))) (f:is (= 253205868 - (solver1 - (uiop:read-file-string "input"))))) + (solver + (uiop:read-file-string "input")))) + (f:is + (= 253907829 + (solver + (uiop:read-file-string "input") 'joker)))) + +;; part2 |