• Re: walk through list and add all n'th item

    From B. Pym@Nobody447095@here-nor-there.org to comp.lang.lisp on Wed Aug 6 14:31:16 2025
    From Newsgroup: comp.lang.lisp

    B. Pym wrote:

    I'm just wondering if there is a lispier way to scan once through a
    list and add each n'th item with n+constant.
    Like kind of apply a list through a vector..
    In my approach i just used the loop macro:
    (defparameter vals '(1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1
    2 3 4 5 6 7 8))
    ...
    CL-USER> (sum-values vals)
    (4 8 12 16 20 24 28 32)

    Can you do better? (i hope you do and I am prepared to bear the shame)

    I see that you ask to "scan once" but still feel awfully
    tempted to reblock the data

    CL-USER> (defun batch (list size)
    (if (endp list)
    '()
    (cons (subseq list 0 size)
    (batch (nthcdr size list) size))))
    BATCH

    CL-USER> (batch vals 8)

    ((1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8) (1 2 3 4 5 6 7 8))

    CL-USER> (defun add (list)
    (reduce (lambda(u v)(mapcar #'+ u v)) list))
    ADD

    CL-USER> (add (batch vals 8))
    (4 8 12 16 20 24 28 32)

    Mark Wooding wrote:

    Or you could just do it the easy way:

    (defun sum-every-softcore (period list)
    (loop with sums = (make-array period :initial-element 0)
    for item in list
    for i = 0 then (mod (1+ i) period)
    do (incf (aref sums i) item)
    finally (return (coerce sums 'list))))

    Gauche Scheme

    (use srfi-42) ;; do-ec

    (define (sum-every-nth n nlist)
    (rlet1 result (make-vector n 0)
    (do-ec (:list x (index i) nlist)
    (inc! (vector-ref result (mod i n)) x))))

    (define vals '(1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1
    2 3 4 5 6 7 8))

    (sum-every-nth 8 vals)

    #(4 8 12 16 20 24 28 32)

    (define (sum-every-nth n nlist)
    (let ((result (make-vector n 0))
    (i (gmki 0 1 n)))
    (dolist (x nlist) (inc! (~ result (i)) x))
    result))

    (define vals '(1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 1
    2 3 4 5 6 7 8))

    (sum-every-nth 8 vals)
    ===>
    #(4 8 12 16 20 24 28 32)

    Given:

    ;; Make an index generator.
    (define (gmki :optional (start 0) (step #f) (m #f))
    (let ((i start)
    (s step)
    (m m))
    (if m
    (lambda () (begin0 (mod i m) (inc! i s)))
    (if s
    (lambda () (begin0 i (inc! i s)))
    (lambda () (begin0 i (inc! i)))))))
    --
    [T]he problem is that lispniks are as cultish as any other devout group and basically fall down frothing at the mouth if they see [heterodoxy].
    --- Kenny Tilton
    The good news is, it's not Lisp that sucks, but Common Lisp. --- Paul Graham --- Synchronet 3.21a-Linux NewsLink 1.2