From: ·········@olive-it.ch
Subject: walk through list and add all n'th item
Date: 
Message-ID: <5c871dd5-d31b-4556-acb2-e4febfc165e5@d1g2000hsg.googlegroups.com>
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))
(defun sum-values (lst)
  (let ((a 0)
	(b 0)
	(c 0)
	(d 0)
	(e 0)
	(f 0)
	(g 0)
	(h 0))
    (loop
       for item in lst
       for i from 0 to 31

       when (= 0 (mod i 8))
       do (setf a (+ a item))

       when (= 1 (mod i 8))
       do (setf b (+ b item))

       when (= 2 (mod i 8))
       do (setf c (+ c item))

       when (= 3 (mod i 8))
       do (setf d (+ d item))

       when (= 4 (mod i 8))
       do (setf e (+ e item))

       when (= 5 (mod i 8))
       do (setf f (+ f item))

       when (= 6 (mod i 8))
       do (setf g (+ g item))

       when (= 7 (mod i 8))
       do (setf h (+ h item)))

    (list a b c d e f g h)))

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)

From: ······@corporate-world.lisp.de
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <8232c488-5bba-4878-b32e-46511dd4adb2@f63g2000hsf.googlegroups.com>
On May 16, 12:03 am, ·········@olive-it.ch 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))
> (defun sum-values (lst)
>   (let ((a 0)
>         (b 0)
>         (c 0)
>         (d 0)
>         (e 0)
>         (f 0)
>         (g 0)
>         (h 0))
>     (loop
>        for item in lst
>        for i from 0 to 31
>
>        when (= 0 (mod i 8))
>        do (setf a (+ a item))
>
>        when (= 1 (mod i 8))
>        do (setf b (+ b item))
>
>        when (= 2 (mod i 8))
>        do (setf c (+ c item))
>
>        when (= 3 (mod i 8))
>        do (setf d (+ d item))
>
>        when (= 4 (mod i 8))
>        do (setf e (+ e item))
>
>        when (= 5 (mod i 8))
>        do (setf f (+ f item))
>
>        when (= 6 (mod i 8))
>        do (setf g (+ g item))
>
>        when (= 7 (mod i 8))
>        do (setf h (+ h item)))
>
>     (list a b c d e f g h)))
>
> 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)

Check this out:

(loop for (a b c d) on (list 1 2 3 4 5 6 7 8) by #'cddddr
      sum a into a-sum
      sum b into b-sum
      sum c into c-sum
      sum d into d-sum
      finally (return (list a b c d)))
From: ·········@olive-it.ch
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <ffaf479f-67ea-45bc-b1fb-3b23efdf306f@e39g2000hsf.googlegroups.com>
On May 16, 1:48 am, ·······@corporate-world.lisp.de" <······@corporate-
world.lisp.de> wrote:
> On May 16, 12:03 am, ·········@olive-it.ch 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))
> > (defun sum-values (lst)
> >   (let ((a 0)
> >         (b 0)
> >         (c 0)
> >         (d 0)
> >         (e 0)
> >         (f 0)
> >         (g 0)
> >         (h 0))
> >     (loop
> >        for item in lst
> >        for i from 0 to 31
>
> >        when (= 0 (mod i 8))
> >        do (setf a (+ a item))
>
> >        when (= 1 (mod i 8))
> >        do (setf b (+ b item))
>
> >        when (= 2 (mod i 8))
> >        do (setf c (+ c item))
>
> >        when (= 3 (mod i 8))
> >        do (setf d (+ d item))
>
> >        when (= 4 (mod i 8))
> >        do (setf e (+ e item))
>
> >        when (= 5 (mod i 8))
> >        do (setf f (+ f item))
>
> >        when (= 6 (mod i 8))
> >        do (setf g (+ g item))
>
> >        when (= 7 (mod i 8))
> >        do (setf h (+ h item)))
>
> >     (list a b c d e f g h)))
>
> > 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)
>
> Check this out:
>
> (loop for (a b c d) on (list 1 2 3 4 5 6 7 8) by #'cddddr
>       sum a into a-sum
>       sum b into b-sum
>       sum c into c-sum
>       sum d into d-sum
>       finally (return (list a b c d)))

Wow: loop macro rulez, somehow..
just one correction:
(loop for (a b c d) on (list 1 2 3 4 5 6 7 8) by #'cddddr
      sum a into a-sum
      sum b into b-sum
      sum c into c-sum
      sum d into d-sum
      finally (return (list a-sum b-sum c-sum d-sum)))
Yeah, i might consider this code as beautiful
olivier
From: danb
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <1f96a5f1-91b4-4f47-b8ba-943f61d733d4@x35g2000hsb.googlegroups.com>
On May 15, 5:03 pm, ·········@olive-it.ch wrote:
> (defun sum-values (lst)

CL has separate namespaces for variables and functions,
so you don't need to leave off the "i" in list.

>   (let ((a 0) (b 0) (c 0) (d 0)
          (e 0) (f 0) (g 0) (h 0))

This should obviously be an array.

>        when (= 0 (mod i 8))  do (setf a (+ a item))
>        when (= 1 (mod i 8))  do (setf b (+ b item))
>        when (= 2 (mod i 8))  do (setf c (+ c item))
>        ...

Once you use an array, all this junk boils down to
one line with AREF.
Also, (setf x (+ x y)) is the same as (incf x y).

(defun sum-vals (list)
  (let ((sums (vector 0 0 0 0 0 0 0 0)))
    (loop for item in list
          for i from 0
          do (incf (aref sums (mod i 8)) item))
    (coerce sums 'list)))

--Dan

------------------------------------------------
Dan Bensen  http://www.prairienet.org/~dsb/

cl-match:  expressive pattern matching in Lisp
http://common-lisp.net/project/cl-match/
From: Kent M Pitman
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <uhccyaosm.fsf@nhplace.com>
danb <·········@gmail.com> writes:

> (defun sum-vals (list)
>   (let ((sums (vector 0 0 0 0 0 0 0 0)))
>     (loop for item in list
>           for i from 0
>           do (incf (aref sums (mod i 8)) item))
>     (coerce sums 'list)))

I didn't test these very thoroughly, but they may give you some
additional ideas...

(defun sum-vals (list &optional (modulus 8))
  (let ((sums (make-array modulus :initial-element 0)))
    (loop for item in list
          for i from 0
          do (incf (aref sums (mod i modulus)) item))
    ;; Yes, you could (coerce sums 'list) but if it's not homework,
    ;; I suggest just returning the vector rather than wasting time
    ;; coercing it.
    sums))

(defmacro doseq ((var seq) &body forms)
  `(map nil #'(lambda (,var) ,@forms) ,seq))

(defun sum-vals (sequence &key (modulus 8))
  ;; Works on any sequence, not just a list
  (let ((sums (make-array modulus :initial-element 0))
        (i -1))
    (doseq (item sequence)
      (incf (aref sums (mod (incf i) modulus)) item))
    sums))

(defun sum-vals (sequence &key (modulus 8))
  ;; Works on any sequence, not just a list
  (let ((sums (make-hash-table)) ;allow sparse
        (i -1))
    (doseq (item sequence)
      (incf (gethash (mod (incf i) modulus) sums 0) item))
    ;; Just return the hash table
    sums))
From: danb
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <4c86ade8-9bae-4528-bbaf-a3d506e968a9@y21g2000hsf.googlegroups.com>
On May 15, 10:52 pm, Kent M Pitman <······@nhplace.com> wrote:
>     ;; Yes, you could (coerce sums 'list) but if it's not homework,
>     ;; I suggest just returning the vector rather than wasting time
>     ;; coercing it.

Agreed.  I was just following the spec, but I should have
gone ahead and changed it.

> (defmacro doseq ((var seq) &body forms)
>   `(map nil #'(lambda (,var) ,@forms) ,seq))

>     (doseq (item sequence)
>       (incf (aref sums (mod (incf i) modulus)) item))

I don't see the point of using map functions for iteration.
Even though multiple cpus weren't as common in the 80s as
they are now, surely concurrency must have at least been
discussed.  Or was mapping order locked in even earlier?

--Dan

------------------------------------------------
Dan Bensen  http://www.prairienet.org/~dsb/

cl-match:  expressive pattern matching in Lisp
http://common-lisp.net/project/cl-match/
From: Kent M Pitman
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <u8wy9s8s9.fsf@nhplace.com>
danb <·········@gmail.com> writes:

> On May 15, 10:52 pm, Kent M Pitman <······@nhplace.com> wrote:
> ...
> > (defmacro doseq ((var seq) &body forms)
> >   `(map nil #'(lambda (,var) ,@forms) ,seq))
> 
> >     (doseq (item sequence)
> >       (incf (aref sums (mod (incf i) modulus)) item))
> 
> I don't see the point of using map functions for iteration.

In this case, the point was that MAP is implemented to efficiently
map over both vectors and lists, which to do otherwise requires two
different macroexpansions since list iteration and vector iteration
are done quite differently in CL.

> Even though multiple cpus weren't as common in the 80s as
> they are now, surely concurrency must have at least been
> discussed.  Or was mapping order locked in even earlier?

Certainly we had process locks and we had special variables that
worked right across processes and all kinds of other stuff.  And yes,
left-to-right order of evaluation is a grand tradition that goes back
before CL.  But also, you wouldn't have been able to change just one
function--what about things like GET that work on property lists of
globally accessible symbols?  There's no way to "lock" a symbol, so if
you parallelized MAP but didn't address synchronization of other
operations that your mapped function might call, what difference would
it make. There are, of course, ways to address such problems--the
problems I cite are not without solution.  But one of the ways to
address things is not "sneak in a different semantics to some of the
operators and hope no one notices".
From: Ken Tilton
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <482cc469$0$11632$607ed4bc@cv.net>
·········@olive-it.ch 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))
> (defun sum-values (lst)
>   (let ((a 0)
> 	(b 0)
> 	(c 0)
> 	(d 0)
> 	(e 0)
> 	(f 0)
> 	(g 0)
> 	(h 0))
>     (loop
>        for item in lst
>        for i from 0 to 31
> 
>        when (= 0 (mod i 8))
>        do (setf a (+ a item))
> 
>        when (= 1 (mod i 8))
>        do (setf b (+ b item))
> 
>        when (= 2 (mod i 8))
>        do (setf c (+ c item))
> 
>        when (= 3 (mod i 8))
>        do (setf d (+ d item))
> 
>        when (= 4 (mod i 8))
>        do (setf e (+ e item))
> 
>        when (= 5 (mod i 8))
>        do (setf f (+ f item))
> 
>        when (= 6 (mod i 8))
>        do (setf g (+ g item))
> 
>        when (= 7 (mod i 8))
>        do (setf h (+ h item)))
> 
>     (list a b c d e f g h)))
> 
> CL-USER> (sum-values vals)
> (4 8 12 16 20 24 28 32)

I smell homework.

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

And turn it in? :)

What application requires this algorithm?

kenny

-- 
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
ECLM rant: 
http://video.google.com/videoplay?docid=-1331906677993764413&hl=en
ECLM talk: 
http://video.google.com/videoplay?docid=-9173722505157942928&q=&hl=en
From: ·········@olive-it.ch
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <3d064efb-2bb2-4d22-b294-9a3e10e86886@r66g2000hsg.googlegroups.com>
On May 16, 1:16 am, Ken Tilton <···········@optonline.net> wrote:


> I smell homework.
>
Ahh, is my solution that bad?
>
>
> > Can you do better? (i hope you do and I am prepared to bear the shame)
>
> And turn it in? :)
Nope, no homework, well yes, my homework for me
> What application requires this algorithm?
>
Got some statistics from a form with four block of questions where
each first, second answer etc. give some value. Now the analysis
requires to sum the values for each "type" of question. This sum is
used as a indicator of type of management.
Like those "how much does he love you" questions in those magazines

q1-1) How fast do you hit your co-worker?        answer: 0 2 4 6
q1-2) How fast do you shout at your co-worker?   answer: 0 2 4 6
..
then
q2-1) How hard do you hit your co-worker?        answer: 0 2 4 6
q2-2) How load do you shout at your co-worker    answer: 0 2 4 6

etc.
four groups at eight question each,
Anyhow i thought this would be some application of a more general
vector sub-routine, now i'm totaly ashamed to be held as a student
asking others to do their homework..
Bah, i'm content with my solution (for now) and am well over the clock
night
olivier
> kenny
>
> --http://smuglispweeny.blogspot.com/http://www.theoryyalgebra.com/
> ECLM rant:http://video.google.com/videoplay?docid=-1331906677993764413&hl=en
> ECLM talk:http://video.google.com/videoplay?docid=-9173722505157942928&q=&hl=en
From: Ken Tilton
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <482ce68b$0$15168$607ed4bc@cv.net>
·········@olive-it.ch wrote:
> On May 16, 1:16 am, Ken Tilton <···········@optonline.net> wrote:
> 
> 
> 
>>I smell homework.
>>
> 
> Ahh, is my solution that bad?
> 
>>
>>>Can you do better? (i hope you do and I am prepared to bear the shame)
>>
>>And turn it in? :)
> 
> Nope, no homework, well yes, my homework for me
> 
>>What application requires this algorithm?
>>
> 
> Got some statistics from a form with four block of questions where
> each first, second answer etc. give some value. Now the analysis
> requires to sum the values for each "type" of question. This sum is
> used as a indicator of type of management.
> Like those "how much does he love you" questions in those magazines
> 
> q1-1) How fast do you hit your co-worker?        answer: 0 2 4 6
> q1-2) How fast do you shout at your co-worker?   answer: 0 2 4 6
> ..
> then
> q2-1) How hard do you hit your co-worker?        answer: 0 2 4 6
> q2-2) How load do you shout at your co-worker    answer: 0 2 4 6
> 
> etc.
> four groups at eight question each,
> Anyhow i thought this would be some application of a more general
> vector sub-routine, now i'm totaly ashamed to be held as a student
> asking others to do their homework..
> Bah, i'm content with my solution (for now) and am well over the clock
> night

Well, if you think about it, you were not asking a Lisp or loop 
question, you were (sorry) asking a student-level question 
HLL-independent question. You got as far as taking the mod to get a 
return value 0-7 to tell you what thing to update, but forgot (perhaps 
dazzled by the general novelty of Lisp and loop) how hotshot kickass 
programmers like you and me normally use a number in a tight range to 
tell us what place to update. (Hint: someone else already reminded you.)

:)

kt

-- 
http://smuglispweeny.blogspot.com/
http://www.theoryyalgebra.com/
ECLM rant: 
http://video.google.com/videoplay?docid=-1331906677993764413&hl=en
ECLM talk: 
http://video.google.com/videoplay?docid=-9173722505157942928&q=&hl=en
From: Daniel Weinreb
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <4831471E.8070808@alum.mit.edu>
·········@olive-it.ch wrote:
> On May 16, 1:16 am, Ken Tilton <···········@optonline.net> wrote:
> 
> 
>> I smell homework.
>>
> Ahh, is my solution that bad?

What he meant was, this problem sounds as if it's a homework
assigment for a class at a school, and some of us on comp.lang.lisp
feel that providing answers for someone's homework is to
aid in cheating.  So he suspects that you are trying to cheat
on a homework assignment.  (I take no position; I'm just
clarifying his mail for you.)
From: Kent M Pitman
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <ulk2b9l8z.fsf@nhplace.com>
·········@olive-it.ch writes:

> 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. [...]
> Can you do better? (i hope you do and I am prepared to bear the shame)

Better according to what criterion?  Contrary to the belief of some,
the world is not a total ordering of items which have a uniquely
determined goodness value and can be trivially sorted. :)

Faster to execute? Shorter definition? More extensible? ...

Btw, of curiosity, is this homework?  (Just useful to know.)
From: Alan Crowe
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <86ve1d98wd.fsf@cawtech.freeserve.co.uk>
·········@olive-it.ch writes:

> 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)

Alan Crowe
Edinburgh
Scotland
From: Mark Wooding
Subject: Re: walk through list and add all n'th item
Date: 
Message-ID: <slrng36r83.ihm.mdw@metalzone.distorted.org.uk>
·········@olive-it.ch <·········@olive-it.ch> 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.

Yes.

> Like kind of apply a list through a vector..

Why not use a vector, then?

> (defun sum-values (lst)
>   (let ((a 0)
> 	(b 0)
> 	(c 0)
> 	(d 0)
> 	(e 0)
> 	(f 0)
> 	(g 0)
> 	(h 0))
>     (loop
>        for item in lst
>        for i from 0 to 31
>
>        when (= 0 (mod i 8))
>        do (setf a (+ a item))

Arrgh, kill me now.

Your code is hard to extend to other periods.  Here's one way to do it;
it's Lispy, in that it involves processing code as data; I daresay the
technique is useful -- in other applications.

(let ((summers (make-hash-table)))
  (defun sum-every-hardcore (period list)
    (funcall (or (gethash period summers)
		 (setf (gethash period summers)
		       (let ((vars (loop repeat period collect (gensym))))
			 (compile nil
				  `(lambda (list)
				     (let (,@(mapcar (lambda (var) `(,var 0))
						     vars))
				       (tagbody
					top
					  ,@(mapcan (lambda (var)
						      `((unless list
							  (go done))
							(incf ,var
							      (pop list))))
						    vars)
					  (go top)
					done)
				       (list ,@vars)))))))
	     list)))

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))))

(Doing things the easy way is definitely Lispy.)

-- [mdw]