Pairing elements from list - MAPCAR version

Discussion of Common Lisp

Pairing elements from list - MAPCAR version

Postby 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.
Ajschylos
 
Posts: 18
Joined: Wed Jan 07, 2009 12:44 pm

Re: Pairing elements from list - MAPCAR version

Postby nuntius » Wed Jan 07, 2009 6:28 pm

Replace the MAPLIST with MAPCON and the wynik with nil.
User avatar
nuntius
 
Posts: 500
Joined: Sat Aug 09, 2008 10:44 am
Location: Burlington, MA

Re: Pairing elements from list - MAPCAR version

Postby 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.
Ajschylos
 
Posts: 18
Joined: Wed Jan 07, 2009 12:44 pm

Re: Pairing elements from list - MAPCAR version

Postby 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...
User avatar
Kohath
 
Posts: 53
Joined: Mon Jul 07, 2008 8:06 pm
Location: Toowoomba, Queensland, Australia

Re: Pairing elements from list - MAPCAR version

Postby 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.
Ajschylos
 
Posts: 18
Joined: Wed Jan 07, 2009 12:44 pm


Return to Common Lisp

Who is online

Users browsing this forum: Google [Bot], Yahoo [Bot] and 4 guests