• Re: Slow Loop (alternatives in lisp?)

    From B. Pym@21:1/5 to All on Sat Aug 17 09:30:28 2024
    (defun distribution1 (items values test)
    (let ((table (make-hash-table :test test)))
    (loop for item in items
    for value in values
    do (incf (gethash item table 0) value))
    (let ((items-list nil))
    (maphash (lambda (item sum-value)
    (push (cons item sum-value) items-list))
    table)
    (sort items-list #'> :key #'cdr))))

    An example call:

    CL-USER 58 > (distribution1 '("a" "b" "c" "b" "a" "f" "e" "g"
    "h" "k" "z" "k" "r" "u" "f")
    '(1 5 8 7 14 8 3 7 9 4 3 21 5 7 9)
    #'equal)
    (("k" . 25) ("f" . 17) ("a" . 15) ("b" . 12) ("h" . 9) ("c" . 8)
    ("g" . 7) ("u" . 7) ("r" . 5) ("e" . 3) ("z" . 3))

    newLISP

    Let's simply use an association list.

    (macro (ainc! Alist Key Value Function Deflt)
    (local (E-Message Val Func Def)
    (setq Func Function)
    (if (true? Func)
    (setq Val Value)
    (begin (setq Func +) (setq Val (or Value 1))))
    (setq Def Deflt)
    (if (= nil Def) (setq Def 0))
    (unless
    (catch
    (setf (assoc Key Alist)
    (list ($it 0) (Func Val ($it 1))))
    'E-Message)
    (setf Alist (cons (list Key (Func Val Def)) Alist)))))

    (define (distribution1 items vals)
    (let (table '())
    (dolist (it items) (ainc! table it (pop vals)))
    (sort table (fn (a b) (> (a 1) (b 1))))))

    (distribution1
    '("a" "b" "c" "b" "a" "f" "e" "g" "h" "k" "z" "k" "r" "u" "f")
    '(1 5 8 7 14 8 3 7 9 4 3 21 5 7 9))

    ===>
    (("k" 25) ("f" 17) ("a" 15) ("b" 12) ("h" 9) ("c" 8) ("g" 7)
    ("u" 7) ("r" 5) ("e" 3) ("z" 3))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)