Sujet : Re: walk through list and add all n'th item
De : Nobody447095 (at) *nospam* here-nor-there.org (B. Pym)
Groupes : comp.lang.lispDate : 30. Aug 2024, 18:42:30
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <vasspk$inrq$1@dont-email.me>
User-Agent : XanaNews/1.18.1.6
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)