Looking for hints on style and clarity re. below. While I'm not saying speed is irrelevant, it's less of a priority than style & avoiding bad habits at this point. Focus is on clean use of fundamentals of the language.
Summary of task:
Take a list and return a list indicating the number of times each (eql) element appears, sorted from most common element to least common."
Example run with required output:
> (occurrences '(a b a d a c d c a))
((A . 4) (C . 2) (D . 2) (B . 1))
My solution:
(defun occurrences (lst)
"Takes a list and returns a list indicating the number of times each (eql)
element appears, sorted from most common element to least common."
(occurrences2 lst (mapcar #'(lambda (x) (cons x 0))
(remove-dups lst))))
(defun occurrences2 (lst res)
"Update res, an alist which already contains all needed entries with all
values set to zero, with frequencies of occurrence as found in lst"
(if (null lst)
res ; todo: add a sort here on cdr of each element
(occurrences2 (cdr lst)
(mapcar #'(lambda (x)
(if (eql (car x) (car lst))
(cons (car x) (+ (cdr x) 1))
x))
res))))
(defun remove-dups (lst)
(if (null lst)
nil
(adjoin (car lst) (remove-dups (cdr lst)))))
"(works, omitting the sort)"
. \$\endgroup\$