(defun input-lines (f) (with-open-file (s f) (loop for line = (read-line s nil 'eof) until (eq line 'eof) collect line))) (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 parse-integers (string) (loop for i = 0 then (cadr o) as o = (multiple-value-list (parse-integer string :start i :junk-allowed t)) as n = (car o) while n collect n)) (defun card-winning (winning numbers) (loop for number in numbers count (member number winning))) (defun line-winning (line) (let ((card-info (split-by-char #\| (cadr (split-by-char #\: line))))) (let ((winning (parse-integers (car card-info))) (numbers (parse-integers (cadr card-info)))) (card-winning winning numbers)))) (defun line-points (line) (ash 1 (1- (line-winning line)))) (defun solve1 (f) (let ((lines (input-lines f))) (reduce #'+ (mapcar 'line-points lines)))) (defun solve2 (f) (let ((lines (input-lines f))) (let ((arr (make-array (length lines) :initial-element 1))) (loop for i = 0 then (1+ i) for line in lines as count = (line-winning line) as v = (aref arr i) do (loop for j from 1 to count as e = (aref arr (+ i j)) do (setf (aref arr (+ i j)) (+ v e))) sum v)))) (print (solve1 "data/04/example.txt")) ;; 13 (print (solve1 "data/04/input.txt")) ;; 24160 (print (solve2 "data/04/example.txt")) ;; 30 (print (solve2 "data/04/input.txt")) ;; 5659035