(ql:quickload :cl-ppcre) (defun parse-input (input) (cl-ppcre:split "\\n" (uiop:read-file-string input))) (defun get-score (c) (cond ((lower-case-p c) (- (char-code c) 96)) ((upper-case-p c) (- (char-code c) 38)))) (defun calc-score-one (rucksack) (let* ((c1 (subseq rucksack 0 (/ (length rucksack) 2))) (c2 (subseq rucksack (/ (length rucksack) 2) (length rucksack)))) (loop :for c :across c1 :if (find c c2) :return (get-score c)))) (defun part-one (input) (reduce '+ (mapcar #'calc-score-one (parse-input input)))) (defun calc-score-two (rucksacks) (let* ((r1 (first rucksacks)) (r2 (second rucksacks)) (r3 (third rucksacks))) (loop :for c :across r1 :if (and (find c r2) (find c r3)) :return (get-score c)))) (defun part-two (input) (reduce '+ (loop :for (r1 r2 r3) :on (parse-input input) :by 'cdddr :collect (calc-score-two (list r1 r2 r3)))))