Pairing elements from list - MAPCAR version

Discussion of Common Lisp
Post Reply
Ajschylos
Posts: 18
Joined: Wed Jan 07, 2009 12:44 pm

Pairing elements from list - MAPCAR version

Post by Ajschylos » Wed Jan 07, 2009 1:03 pm

Hi everybody,
I've started learning LISP again after several unsuccessful attempts, but now I gain some progress.

I am stuck with the problem:
Input: list of consecutive primes i.e. '(2 3 5 7 11)
Output: list of their pairwise products without duplication '(4 6 10 14 22 9 15 21 33 25 35 55 49 77 121)
I can imagine imperative solution with do-list or so.
Recursive solution is also very simple:

Code: Select all

(defun p-mul (l)
"Simple recursive version
 Input: List of different primes.
 Returns: List of pairwise multiplied elements of list l with no  duplicates"

  (if (null (rest l)) 
      (list (* (car l) (car l))) 
      (append (mapcar #'(lambda (x) (* x (first l))) 
                      l) 
              (p-mul (cdr l)))
      )
  )
Works pretty well, but I can't do it with using mapcar's, maplist's , and possibly other members of the family.

My last most successful solution is:

Code: Select all

(defun pair-mult (l)
"MAP___ version
 Input: List of different primes.
 Returns: List of pairwise multiplied elements of list l with no  duplicates"

(maplist #'(lambda (sub)  
        (mapcar #'(lambda (y x) (* x y))
                    sub l))

                 l)

)



Which applied to the list '(2 3 5 7 11) gives: ((4 9 25 49 121) (6 15 35 77) (10 21 55) (14 33) (22)) an awfully nested answer.

I don't want to 'flatten' this answer, I am looking for an elegant map***'s expression.

Does it exist?

Adam.
Last edited by Ajschylos on Wed Jan 07, 2009 10:44 pm, edited 1 time in total.

nuntius
Posts: 538
Joined: Sat Aug 09, 2008 10:44 am
Location: Newton, MA

Re: Pairing elements from list - MAPCAR version

Post by nuntius » Wed Jan 07, 2009 6:28 pm

Replace the MAPLIST with MAPCON and the wynik with nil.

Ajschylos
Posts: 18
Joined: Wed Jan 07, 2009 12:44 pm

Re: Pairing elements from list - MAPCAR version

Post by Ajschylos » Wed Jan 07, 2009 10:46 pm

I am very sorry nuntius, the code I posted earlier works of corsue if "wynik" is global variable,
now I changed code so that function should return the list. That was my mistake. Adam.

Kohath
Posts: 61
Joined: Mon Jul 07, 2008 8:06 pm
Location: Toowoomba, Queensland, Australia
Contact:

Re: Pairing elements from list - MAPCAR version

Post by Kohath » Thu Jan 08, 2009 8:16 pm

If you're still interested, here's another way of doing it, also using curry for full flavour :D:

Code: Select all

(mapcon #'(lambda (sub)
            (mapcar (curry #'* (car sub)) sub))
        l)
It does it in the same order of the results that you originally posted.

P.S. Nice pickup on mapcon - those names confuse me every time...

Ajschylos
Posts: 18
Joined: Wed Jan 07, 2009 12:44 pm

Re: Pairing elements from list - MAPCAR version

Post by Ajschylos » Fri Jan 09, 2009 6:13 am

Thank you, this is a piece of beautiful code indeed.
I've found solution very similar:

Code: Select all

(defun par-mul (l)

 (mapcon #'(lambda (sub) 
             (mapcar #'(lambda (x) (* x (first sub))) 
                     sub)) 
         l)
)
I must analyze the difference between two approaches.
Thank's a lot. Adam.

Post Reply