Path: ...!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: "B. Pym" Newsgroups: comp.lang.lisp Subject: Re: walk through list and add all n'th item Date: Fri, 30 Aug 2024 16:42:30 -0000 (UTC) Organization: A noiseless patient Spider Lines: 59 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Injection-Date: Fri, 30 Aug 2024 18:42:30 +0200 (CEST) Injection-Info: dont-email.me; posting-host="7471b6bf57a1160866342d87b5967bc4"; logging-data="614266"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/o7aYssbvDID9Wl+tvSPUG" User-Agent: XanaNews/1.18.1.6 Cancel-Lock: sha1:0eNM2Fx+b8UFt5ydFh0W0fasKqw= Bytes: 2563 > > 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)