K isn't Lisp


On comp.lang.lisp, Svein Ove Aas writes:

Niklas Brunberg wrote:

> We have a list of elements, some are duplicates. We're trying to figure
> out how to find the duplicate elements and increase a counter value by 1
> for each instance of the element found. The list consists of lists with
> two elements, the first being the incremental counter, the second being
> the string sought. Example:
> 
> ((1 "one") (1 "two") (1 "three") (1 "one") (1 "four") (1 "two"))
> 
> The result should be:
> 
> ((2 "one") (2 "two") (1 "three") (1 "four"))
> 
> 
> This is the function for adding 1 (incremental counter element):
> 
> (defun add-one-to-n (indata)
>    (setq n (car indata))
>    (setq outdata
>      (cons (+ 1 n) (cdr indata))))
> 
> Any ideas on how we should go about achieving this?

I'd use a hash table, much like this:

(defun count (list)
  (let ((hash (make-hash-table)))
    (dolist (el list)
      (incf (gethash (cadr el) hash 0) (car el)))
    (let (result)
      (maphash (lambda (key val)
                 (push (list val key) result))
         hash)
      result)))

that is,

  v:((1;"one");(1;"two");(1;"three");(1;"one");(1;"four");(1;"two"))
  +(#:'=v[;1];?v[;1])
((2;"one")
 (2;"two")
 (1;"three")
 (1;"four"))

that is,

	flip(count each group v[;1];unique v[;1])