#-(and) " P08 (**) Eliminate consecutive duplicates of list elements. If a list contains repeated elements they should be replaced with a single copy of the element. The order of the elements should not be changed. Example: * (compress '(a a a a b c c a a d e e e e)) (A B C A D E) " ;; Nice recursive solution: (defun compress (list) (labels ((compress-run (item list) (cond ((null list) (list item)) ((eql item (first list)) (compress-run item (rest list))) (t (cons item (compress-run (first list) (rest list))))))) (cond ((null list) list) ((null (rest list)) list) (t (compress-run (first list) (rest list)))))) ;; Iterative solution: (defun compress (list) (cond ((null list) list) ((null (rest list)) list) (t (loop :with result = '() :with item = (first list) :for other :in (rest list) :do (unless (eql item other) (push item result) (setf item other)) :finally (push item result) (return (nreverse result)))))) ;; Smartass solution, using Common Lisp reduce: (defun compress (list) (reduce (lambda (item result) (cond ((endp result) (list item)) ((eql (first result) item) result) (t (cons item result)))) list :from-end t :initial-value '())) ;; Without :from-end, we need a reverse, and notice the order of the ;; arguments to the function: (defun compress (list) (nreverse (reduce (lambda (result item) (cond ((endp result) (list item)) ((eql (first result) item) result) (t (cons item result)))) list :initial-value '()))) ;;;; THE END ;;;;