(defun count-car (list element)
(if (and list (eql element (car list))) (1+ (count-car (cdr list) element)) 0))
(defun pack-list (line &optional ack)
(let ((seqlen (min 26 (count-car line (car line)))))
(cond ((null line) ack)
((> seqlen 2) (pack-list
(nthcdr seqlen line)
(cons (cons seqlen (list (car line))) ack)))
((and (eql (caar ack) 1) (< (length (cdar ack)) 26))
(pack-list (cdr line)
(cons (cons (caar ack)
(cons (car line) (cdar ack)))
(cdr ack))))
(t (pack-list (cdr line) (cons (cons 1 (list (car line))) ack))))))
(defun build-string (list)
(format nil "~{~A~}"
(mapcar (lambda (e) (format nil "~A~{~C~}"
(code-char (if (eql (car e) 1)
(+ 96 (length (cdr e)))
(+ 64 (car e))))
(reverse (cdr e))))
(reverse list))))
(defun pack-string (string)
(build-string (pack-list (coerce string 'list))))