(load (sb-ext:posix-getenv "ASDF")) (asdf:load-system 'str) (asdf:load-system 'alexandria) (defun parse-line (line) (str:match line ((first "-" last) (cons (parse-integer first) (parse-integer last))) ((test) (parse-integer test)) ) ) (parse-line "5-15") (parse-line "6") (defun in-set-last (item setp) (let ((first (car setp)) (last (cdr setp))) (if (and (>= item first) (<= item last)) (+ last 1)))) (defun in-set-first (item setp) (let ((first (car setp)) (last (cdr setp))) (if (and (>= item first) (<= item last)) (- first 1)))) (in-set-first 5 (cons 5 15)) (defun in-superset (item superset test) (loop for setp in superset when (funcall test item setp) return (funcall test item setp)) ) (in-superset 10 (list (parse-line "5-15") (parse-line "20-30")) #'in-set-first) (in-superset 10 (list (parse-line "5-15") (parse-line "20-30")) #'in-set-last) (defun set-transform (set superset) (let ((first (car set)) (last (cdr set))) (setq first (or (in-superset first superset #'in-set-last) first)) (setq last (or (in-superset last superset #'in-set-first) last)) (if (< first last) (cons first last)))) (set-transform (cons 14 115) (list (cons 5 15) (cons 20 30))) (defun count-fresh-ingredients (filename) (let ((superset ()) (fresh-count 0)) (loop for line in (str:lines (str:from-file filename) :omit-nulls t) do (let ((parsed (parse-line line))) (if (consp parsed) ; consp (alexandria:if-let (parsed (set-transform parsed superset)) (setf superset (push parsed superset))) ; integerp (if (in-superset parsed superset #'in-set-last) (setq fresh-count (+ fresh-count 1))) ))) ;; (print superset) fresh-count)) (count-fresh-ingredients "05example.txt") (count-fresh-ingredients "05data.txt")