Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

take a sequence of numbers 2 at a time, print numbers and their product?

Skip to first unread message

livingcosmos.org

unread,
Dec 27, 2007, 5:34:28 PM12/27/07
to
How would you take a sequence of numbers in groups of 2 and print out
the numbers and their product?

Here is my solution, but I'm sure some li5p h4x0r has a much more 1337
solution :)

(setf nums (vector 21 47
23 43
24 29
22 28
22 53
31 36
22 56
31 72))

(loop for i from 0 below (car (array-dimensions nums)) by 2
do (progn
(let ((a (aref nums i))
(b (aref nums (1+ i))))
(format t "~A * ~A = ~A~%" a b (* a b)))))

Kaz Kylheku

unread,
Dec 27, 2007, 5:56:17 PM12/27/07
to
On Dec 27, 2:34 pm, "livingcosmos.org" <metap...@gmail.com> wrote:
> How would you take a sequence of numbers in groups of 2 and print out
> the numbers and their product?
>
> Here is my solution, but I'm sure some li5p h4x0r has a much more 1337
> solution :)
>
> (setf nums (vector 21 47
>                    23 43
>                    24 29
>                    22 28
>                    22 53
>                    31 36
>                    22 56
>                    31 72))
>
> (loop for i from 0 below (car (array-dimensions nums)) by 2

What's wrong with (length nums)?

If the array to be multi-dimensional, your 1D arefs won't work anyway.

>      do (progn

The do clause already takes a list of forms; no progn required.

>           (let ((a (aref nums i))
>                 (b (aref nums (1+ i))))
>           (format t "~A * ~A = ~A~%" a b (* a b)))))

It's perhaps more useful to collect the results than print.

State machine approach:

(loop for x across nums
with acc
if (null acc) do
(setf acc x)
else
collect (* x acc) and do
(setf acc nil))

Rainer Joswig

unread,
Dec 27, 2007, 6:25:11 PM12/27/07
to
In article
<403a2cc2-3f9d-4e34...@i12g2000prf.googlegroups.com>,
"livingcosmos.org" <meta...@gmail.com> wrote:

> How would you take a sequence of numbers in groups of 2 and print out
> the numbers and their product?
>
> Here is my solution, but I'm sure some li5p h4x0r has a much more 1337
> solution :)
>
> (setf nums (vector 21 47
> 23 43
> 24 29
> 22 28
> 22 53
> 31 36
> 22 56
> 31 72))

Remember that variables are introduced with DEFPARAMETER (or DEFVAR)
and not with SETF.

Also remember that all top-level variables should be by convention
written like this: *nums*

>
> (loop for i from 0 below (car (array-dimensions nums)) by 2
> do (progn
> (let ((a (aref nums i))
> (b (aref nums (1+ i))))
> (format t "~A * ~A = ~A~%" a b (* a b)))))

ARRAY-DIMENSION is not the best operation for a vector in
general, since the vector could be one with a fill-pointer.
LENGTH will give you the real used length of a vector.

This solution is basically the same as yours but a bit
differently written:

(loop with size = (length *nums*)
for i from 0 below size by 2
for j from 1 below size by 2
for a = (aref *nums* i) and b = (aref *nums* j)
do (format t "~A * ~A = ~A~%" a b (* a b)))

--
http://lispm.dyndns.org/

Mark Tarver

unread,
Dec 27, 2007, 6:57:07 PM12/27/07
to

People might advise otherwise but I'd try and get away from the loop
construction; it delays your evolution into thinking like a functional
programmer. Think lists and recursion.

Mark

Paul Donnelly

unread,
Dec 27, 2007, 8:37:47 PM12/27/07
to

Unless there's a good reason for all the numbers to be in the same list,
something like (mapcar print-fn set-1 set-2) would be the usual way to go
about this. Print-fn would just be a lambda taking two arguments
containing the format call you used.

Barry Margolin

unread,
Dec 27, 2007, 9:01:50 PM12/27/07
to
In article <pan.2007.12.28....@sbcglobal.net>,
Paul Donnelly <paul-d...@sbcglobal.net> wrote:

But he said you're given a sequence of numbers, not two sequences of
numbers. Obviously this is a homework problem, and you don't get to
change the problem to suit your esthetics.

--
Barry Margolin, bar...@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
*** PLEASE don't copy me on replies, I'll read them in the group ***

Bob Felts

unread,
Dec 27, 2007, 9:27:42 PM12/27/07
to
Kaz Kylheku <kkyl...@gmail.com> wrote:

> On Dec 27, 2:34 pm, "livingcosmos.org" <metap...@gmail.com> wrote:
> > How would you take a sequence of numbers in groups of 2 and print out
> > the numbers and their product?
> >

[...]


>
> It's perhaps more useful to collect the results than print.
>
> State machine approach:
>
> (loop for x across nums
> with acc
> if (null acc) do
> (setf acc x)
> else
> collect (* x acc) and do
> (setf acc nil))

Why not just:

(loop
for x on nums by #'cddr
collect (* (first x) (second x)))


The original problem might then be:

(loop
for x on nums by #'cddr
for a = (first x) and b = (second x)
do

Ken Tilton

unread,
Dec 28, 2007, 12:16:29 AM12/28/07
to

Pfft. We are trying to write applications, not placate some wrathful god
of one paradigm or another. The simple fact is that a loop form will
beat any other syntax hands down in terms of succinctness and clarity
for any requirement other than those where (mapcar 'xxx yyy) or maphash
requiring access to both keys and values will suffice. Lawdy loop is
verbose iterating over both key and value of hash tables -- what went
wrong at /that/ design meeting?!

kt

--
http://www.theoryyalgebra.com/

"In the morning, hear the Way;
in the evening, die content!"
-- Confucius

Steven M. Haflich

unread,
Dec 28, 2007, 2:18:48 AM12/28/07
to
cl-user(2): (defparameter *a* (vector 1 2 3 4 5 6 7 8 9 10))
*a*
cl-user(3): (loop for x across *a*
with y
when y
do (format t "~a * ~a = ~a~%" y x (* x y))
(setf y nil)
else do (setf y x))

This solution is cute but really really ugly. I wouldn't turn
it in for homework...

Paul Donnelly

unread,
Dec 28, 2007, 3:12:14 AM12/28/07
to
On Thu, 27 Dec 2007 21:01:50 -0500, Barry Margolin wrote:

> In article <pan.2007.12.28....@sbcglobal.net>,
> Paul Donnelly <paul-d...@sbcglobal.net> wrote:
>
>> On Thu, 27 Dec 2007 14:34:28 -0800, livingcosmos.org wrote:
>>
>> > How would you take a sequence of numbers in groups of 2 and print out
>> > the numbers and their product?
>>

>> Unless there's a good reason for all the numbers to be in the same list,
>> something like (mapcar print-fn set-1 set-2) would be the usual way to go
>> about this. Print-fn would just be a lambda taking two arguments
>> containing the format call you used.
>
> But he said you're given a sequence of numbers, not two sequences of
> numbers. Obviously this is a homework problem, and you don't get to
> change the problem to suit your esthetics.

Sorry, I forgot we're only allowed to answer the question exactly as asked. :(

Lieven Marchand

unread,
Dec 28, 2007, 7:36:25 AM12/28/07
to
wr...@stablecross.com (Bob Felts) writes:

You can let loop do the destructuring:

(loop for (a b nil) on nums by #'cddr ...)

Nicolas Neuss

unread,
Dec 28, 2007, 9:44:46 AM12/28/07
to
Lieven Marchand <m...@wyrd.be> writes:

> You can let loop do the destructuring:
>
> (loop for (a b nil) on nums by #'cddr ...)

And you can omit nil in this construct.

Nicolas

viper-2

unread,
Dec 28, 2007, 9:58:15 AM12/28/07
to
On Dec 27, 6:57 pm, Mark Tarver <dr.mtar...@ukonline.co.uk> wrote:

> People might advise otherwise but I'd try and get away from the loop
> construction; it delays your evolution into thinking like a functional
> programmer. Think lists and recursion.
>
> Mark


Seconded! I'd rather catch up on Java and Python before delving
into that other language "loop" :-)


>
(setf nums (list 1 2 3 4 5 6 7 8))
(1 2 3 4 5 6 7 8)

>
(defun pair-printer (num-lst)
(when num-lst
(format t "~% ~a ~a ~a" (first num-lst) (second num-lst)
(* (first num-lst) (second num-lst)))
(pair-printer (rest (rest num-lst)))))
PAIR-PRINTER

>
(pair-printer nums)
1 2 2
3 4 12
5 6 30
7 8 56
NIL

You may now add all the bells and whistles to cover odd
numbers of elements etc.

agt

Bob Felts

unread,
Dec 28, 2007, 11:07:33 AM12/28/07
to
Nicolas Neuss <last...@math.uni-karlsruhe.de> wrote:

I actually tried this "(loop for (a b) on nums...)" but it didn't work
for me. The "by #'cddr" is what I needed. Thanks.

Mark Tarver

unread,
Dec 28, 2007, 11:47:03 AM12/28/07
to
> The simple fact is that a loop form will
> beat any other syntax hands down in terms of succinctness and
> clarity

In a modern FPL not always and not here.

(define pp
[X Y | Z] -> (do (output "~A x ~A = ~A~%" X Y (* X Y)) (pp Z))
_ -> _)

Mark

Leandro Rios

unread,
Dec 28, 2007, 12:01:53 PM12/28/07
to
viper-2 escribió:

> On Dec 27, 6:57 pm, Mark Tarver <dr.mtar...@ukonline.co.uk> wrote:
>
>> People might advise otherwise but I'd try and get away from the loop
>> construction; it delays your evolution into thinking like a functional
>> programmer. Think lists and recursion.
>>
>> Mark
>
>
> Seconded! I'd rather catch up on Java and Python before delving
> into that other language "loop" :-)
>


In the same spirit, using a mapping function:

(defparameter *nums* '(21 47


23 43
24 29
22 28
22 53
31 36
22 56
31 72))

(mapc (let ((prev 0))
#'(lambda (x)
(cond ((= prev 0) (setf prev x))
(t (format t "~A * ~A = ~A~%" prev x (* x prev))
(setf prev 0)))))
*nums*)

21 * 47 = 987
23 * 43 = 989
24 * 29 = 696
22 * 28 = 616
22 * 53 = 1166
31 * 36 = 1116
22 * 56 = 1232
31 * 72 = 2232

Leandro

viper-2

unread,
Dec 28, 2007, 12:04:46 PM12/28/07
to

Ever since we returned in that ball of light I've been playing catch
up, but I don't
recognize this language. Which FPL is it?

agt

John Thingstad

unread,
Dec 28, 2007, 12:15:48 PM12/28/07
to
På Fri, 28 Dec 2007 18:04:46 +0100, skrev viper-2
<visi...@mail.infochan.com>:

Qi written by Mark Tarver

http://www.lambdassociates.org/lC21.htm

--------------
John Thingstad

viper-2

unread,
Dec 28, 2007, 4:21:53 PM12/28/07
to
On Dec 28, 12:15 pm, "John Thingstad" <jpth...@online.no> wrote:
> På Fri, 28 Dec 2007 18:04:46 +0100, skrev viper-2
> <visio...@mail.infochan.com>:

> > Ever since we returned in that ball of light I've been playing catch
> > up, but I don't
> > recognize this language. Which FPL is it?
>
> > agt
>
> Qi written by Mark Tarver
>
> http://www.lambdassociates.org/lC21.htm

I am truly impressed. I'll append Qi to my languages-to-learn list.

agt

WJ

unread,
Feb 18, 2011, 3:32:26 PM2/18/11
to
livingcosmos.org wrote:

(let loop ((pairs (vector->list nums)))
(if (null? pairs)
'()
(cons (apply * (take pairs 2)) (loop (cddr pairs)))))

WJ

unread,
Mar 5, 2011, 8:51:40 PM3/5/11
to
Rainer Joswig wrote:

I see that you have chosen the COBOL way by using LOOP.

Now what if you wanted to take the numbers 3 at a time?
You would then have to step three variables: i, j, and k.
And you would need to extract a, b, and c from *nums*.
And you would need to change the format string.

Let's write a generalized procedure that take n numbers
at a time. In Guile Scheme:

(define (tuple-products vec n)
(pair-for-each
(lambda (lst)
(if (= 0 (modulo (length lst) n))
(let ((group (take lst n)))
(format #t "~a = ~a~%"
(string-join (map number->string group) " * ")
(apply * group)))))
(vector->list vec)))


guile> (tuple-products nums 4)
21 * 47 * 23 * 43 = 976143
24 * 29 * 22 * 28 = 428736
22 * 53 * 31 * 36 = 1301256
22 * 56 * 31 * 72 = 2749824


Rainer Joswig

unread,
Mar 6, 2011, 4:37:11 AM3/6/11
to
On 6 Mrz., 02:51, "WJ" <w_a_x_...@yahoo.com> wrote:
> Rainer Joswig wrote:
> > In article
> > <403a2cc2-3f9d-4e34-9066-cdcdf0ccc...@i12g2000prf.googlegroups.com>,

Common Lisp:

(defun tuple-products (list n)
(mapn (lambda (group)
(format t "~%~{~D~^ * ~}" group (reduce '* group)))
list
n))

CL-USER 11 > (tuple-products '(21 47 23 43


24 29 22 28
22 53 31 36
22 56 31 72)

4)

21 * 47 * 23 * 43

24 * 29 * 22 * 28

22 * 53 * 31 * 36

Rainer Joswig

unread,
Mar 6, 2011, 4:41:13 AM3/6/11
to

(format t "~%~{~D~^ * ~} = ~a" group (reduce '* group)))
list
n))


CL-USER 21 > (tuple-products '(21 47 23 43


24 29 22 28
22 53 31 36
22 56 31 72)
4)

21 * 47 * 23 * 43 = 976143

Paul Rubin

unread,
Mar 6, 2011, 4:48:29 AM3/6/11
to
Rainer Joswig <jos...@lisp.de> writes:
> (defun tuple-products (list n)
> (mapn (lambda (group)
> (format t "~%~{~D~^ * ~}" group (reduce '* group)))
> list
> n))

Welcome to GNU CLISP 2.47 (2008-10-23) <http://clisp.cons.org/>
[1]> #'mapn
*** - FUNCTION: undefined function MAPN

Needs more code...

Rainer Joswig

unread,
Mar 6, 2011, 4:50:46 AM3/6/11
to

(defun mapn (f list n)
(loop for l = list then (nthcdr n l)
for l1 = (take-n l n)
while (= (length l1) n)
do (funcall f l1)))

I'm collecting a file with stupid tricks which contain this stuff.
It help's writing code like that...

Rainer Joswig

unread,
Mar 6, 2011, 4:51:00 AM3/6/11
to

helps

Rainer Joswig

unread,
Mar 6, 2011, 4:59:10 AM3/6/11
to
On 6 Mrz., 10:50, Rainer Joswig <jos...@lisp.de> wrote:

(defun take-n (list n)
(loop for e in list
repeat n
collect e))

I'm a bit tired of reposting all the code that has been
written the past decades. Some of that code
is already collected in public libraries. Some not.
Functions like these have been available for
decades. It is not a fault for a newbie
to know the libraries, but somebody like Mr. James,
could have looked around have found them
already.

Examples are:

http://common-lisp.net/project/alexandria/draft/alexandria.html
http://clocc.sourceforge.net/

Rainer Joswig

unread,
Mar 6, 2011, 5:32:16 AM3/6/11
to

Note to myself: 'Don't write anything in a foreign language on a
sunday morning!'

I meant:

It is not a fault for a newbie

to not know the libraries, but somebody like Mr. James,

Message has been deleted

WJ

unread,
May 5, 2011, 3:59:17 AM5/5/11
to
Rainer Joswig wrote:

> In article
> <403a2cc2-3f9d-4e34...@i12g2000prf.googlegroups.com>,


> "livingcosmos.org" <meta...@gmail.com> wrote:
>
> > How would you take a sequence of numbers in groups of 2 and print out
> > the numbers and their product?
> >
> > Here is my solution, but I'm sure some li5p h4x0r has a much more 1337
> > solution :)
> >
> > (setf nums (vector 21 47
> > 23 43
> > 24 29
> > 22 28
> > 22 53
> > 31 36
> > 22 56
> > 31 72))
>
> Remember that variables are introduced with DEFPARAMETER (or DEFVAR)
> and not with SETF.
>
> Also remember that all top-level variables should be by convention

> written like this: nums


>
> >
> > (loop for i from 0 below (car (array-dimensions nums)) by 2
> > do (progn
> > (let ((a (aref nums i))
> > (b (aref nums (1+ i))))
> > (format t "~A * ~A = ~A~%" a b (* a b)))))
>
> ARRAY-DIMENSION is not the best operation for a vector in
> general, since the vector could be one with a fill-pointer.
> LENGTH will give you the real used length of a vector.
>
> This solution is basically the same as yours but a bit
> differently written:
>

> (loop with size = (length nums)


> for i from 0 below size by 2
> for j from 1 below size by 2

> for a = (aref nums i) and b = (aref nums j)


> do (format t "~A * ~A = ~A~%" a b (* a b)))

Arc:

(each x (tuples nums 4)
(println (intersperse " * " x) " = " (apply * x)))

==>

WJ

unread,
May 5, 2011, 5:42:50 AM5/5/11
to
WJ wrote:

>
> (each x (tuples nums 4)
> (println (intersperse " * " x) " = " (apply * x)))

That should be

(prn (intersperse " * " x) " = " (apply * x)))

0 new messages