Page 1 of 2
mapcar or notmapcar
Posted: Tue Aug 31, 2010 8:44 pm
by burton
hi,im trying to get the following:
the input is a list of numbers (integers eg. (1 2 3 4) (5 6 7 8)) and the expected output is ((1*5)+(2*6)+(3*7)+(4*8))/(the sum of the second list).
is there a non-recursive way of solving it?
> (mapcar #'list '(1 2 3 4) '(5 6 7 8))
((1 5) (2 6) (3 7)(4 8))
i was thinking about mapcar, which would do the trick with a little tweaking, but how?
any ideas?
thanks
Re: mapcar or notmapcar
Posted: Tue Aug 31, 2010 8:59 pm
by Duke
Yeah, you want MAPCAR. What you
do not want is #'LIST.

You'll also need one or two REDUCEs (or APPLYs) to get the sums.
Re: mapcar or notmapcar
Posted: Tue Aug 31, 2010 9:56 pm
by Tom
Using MAPCAR and REDUCE is fine. As an alternative approach, you could LOOP.
Code: Select all
(defun notmapcar (list1 list2)
"(list1 x list2) / Sum(list2)"
(if (= (length list1) (length list2))
(loop for val1 in list1
and val2 in list2
sum (* val1 val2) into num
sum val2 into den
finally (return (/ num den)))
(error "The lists are not equal in length.")))
There are many ways to iterate in Common Lisp.
Edit: I was about to close down lisp when I just couldn't resist write a version with MAPCAR. It's not totally functional, but it only traverses the lists once.
Code: Select all
(defun tomapcar (list1 list2)
"(list1 x list2) / Sum(list2)"
(let ((num 0)
(den 0))
(mapcar (lambda (n1 n2)
(incf num (* n1 n2))
(incf den n2))
list1
list2)
(/ num den)))
~ Tom
Re: mapcar or notmapcar
Posted: Wed Sep 01, 2010 4:55 am
by Tordmor
Duke wrote:Yeah, you want MAPCAR. What you
do not want is #'LIST.
What's wrong with #'list?
Re: mapcar or notmapcar
Posted: Wed Sep 01, 2010 5:03 am
by gugamilare
Tordmor wrote:Duke wrote:Yeah, you want MAPCAR. What you
do not want is #'LIST.
What's wrong with #'list?
It does not do what he wants

Re: mapcar or notmapcar
Posted: Wed Sep 01, 2010 12:55 pm
by Warren Wilkinson
Code: Select all
(defun operation (f-list s-list)
(/ (reduce #'+ (mapcar #'* f-list s-list)) (reduce #'+ s-list)))
(operation '(1 2 3 4) '(5 6 7 8)) ;; gives 35/13
Re: mapcar or notmapcar
Posted: Wed Sep 01, 2010 4:39 pm
by burton
Warren, is there a way to get decimals as a result instead of a fraction?
Re: mapcar or notmapcar
Posted: Wed Sep 01, 2010 7:01 pm
by gugamilare
You can use the function FLOAT to convert a number (rational or integer) into a float.
Re: mapcar or notmapcar
Posted: Wed Sep 01, 2010 11:26 pm
by Warren Wilkinson
Why would you want floats/decimal numbers? You could opt to use the more accurate rational numbers throughout your code and then use format's "~f" operator to print the result as a floating point number.
Re: mapcar or notmapcar
Posted: Sun Sep 05, 2010 6:08 am
by findinglisp
Warren Wilkinson wrote:Why would you want floats/decimal numbers?
Depends on the code. Floats will generally be handled with greater performance by the hardware; rationals are Lisp-only concepts that have to be manipulated in software, with many extra steps. But as you point out, rationals will keep better precision through a many-step calculation.