multiplying each element of a list with each element of another list in lisp - lisp

i want to write a function that accepts 2 lists as argument and return multiplication of them in a list.
like this:
(3 4) (3 5 6) => (9 15 18 12 20 24)
this is the code that i've came up with but i receive an error which is telling me that i have too few arguments for map.
(defun multip (lst lst2)
;this is a function to flatten the result
(defun flatten (tree)
(let ((result '()))
(labels ((scan (item)
(if (listp item)
(map nil #'scan item)
(push item result))))
(scan tree))
(nreverse result)))
(flatten (map (lambda (i) (map (lambda (j) (* i j)) lst )) lst2))
)
(write (multip '(3 4 6) '(3 2) ))
i can not understand what am i doing wrong. i appreciate your comment.

You don't need to flatten the list, if you create a flat list.
Use MAPCAN:
CL-USER 4 > (flet ((mult (a b)
(mapcan #'(lambda (a1)
(mapcar (lambda (b1) (* a1 b1))
b))
a)))
(mult '(3 4) '(3 5 6)))
(9 15 18 12 20 24)

You should use mapcar instead of map:
(mapcar (lambda (i) (mapcar (lambda (j) (* i j)) lst )) lst2))
These are two different functions: mapcar maps a function on one or more lists, and requires at least two arguments, while map is the equivalent but for any kind of sequences (e.g. vectors), and requires an additional argument specifying the type of the result. See the reference for map here, and the reference for mapcar here.
Style
You are using a defun inside another defun: this is not good style, since every time multip is called it redefines globally the function flatten. You should either define flatten externally, only once, or use a local declaration of function with flet or labels (as for the internal function scan inside flatten.)
For alternative and more simple definitions of flatten, you can see this question in SO.

Related

Using racket to recursively sum nested lists within a list of permutations

I have a list of numbers and a list of operators in racket.
(define numList (list 5 25))
(define ops '(+ *))
I am using the cartesian-product to join the operators to each possible permutation of the list of numbers.
(cartesian-product ops (permutations numList))
which gives the following result;
'((+ (5 25))
(+ (25 5))
(* (5 25))
(* (25 5)))
I want to sum each nested list, ie (+ (5 25)) and then add them to a list.
I have managed to do the following so far using the eval keyword;
(define ns (make-base-namespace))
(list (eval
(flatten
(cadr
(cartesian-product ops (permutations numList))))ns ))
Which removes the nesting of each list and performs the sum on the first 3 elements and returns a value of 50 (+ (5 25)).
I want to perform this recursively on each nested section before the flatten is performed. I know that I'll be able to use remove-duplicates too.
I'm new to Racket, but here's what i have so far;
(define (evalCart l)
(if (null? l)
0
(list
(eval
(flatten
(cadr
(cartesian-product ops (permutations numList)))) ns ) (evalCart (car
l)))))
eval is a bit overkill. You can instead determine which procedure you want by comparing for symbol equality. Since racket has first class procedures, you can just return the procedure itself. For instance:
(define (get-procedure term)
(case term
[(+) +]
[(-) -]
[(*) *]
[(/) /]))
If you don't know case you can use a cond form
(cond [(eq? term '+) +] ...
Then you can use this with apply as in
(define (evaluate term)
(define procedure (get-procedure (first term)))
(define arguments (second term))
(apply procedure arguments))
Then you can map the procedure evaluate as in
(map evaluate (cartesian-product ops (permutations numList)))
This will give you a list of numbers. In the case of the list of four elements you gave, you would get '(30 30 125 125), which I believe is what you're looking for.

Why (apply and '(1 2 3)) doesn't work while (and 1 2 3) works in R5RS? [duplicate]

This question already has answers here:
Using AND with the apply function in Scheme
(9 answers)
Closed 9 years ago.
I tried it in Racket like this
> (apply and '(1 2 3))
. and: bad syntax in: and
> (and 1 2 3)
3
Does anyone have ideas about this?
and is not a function, it's a macro, so you cannot pass it around like a function.
The reason and is a macro, is to enable short-circuiting behaviour. You can make your own non-short-circuiting version:
(define (my-and . items)
(if (null? items) #t
(let loop ((test (car items))
(rest (cdr items)))
(cond ((null? rest) test)
(test (loop (car rest) (cdr rest)))
(else #f)))))
and my-and can be used with apply.
For comparison, here's what the macro (which does do short-circuiting) looks like:
(define-syntax and
(syntax-rules ()
((and) #t)
((and test) test)
((and test rest ...) (if test
(and rest ...)
#f))))
Chris Jester-Young's answer is right, but there's one other point I want to highlight. The standard and operator is a macro which delays the evaluation of its arguments, by (essentially, if not exactly) turning (and a b c) into (if a (if b c #f) #f). This means that if a is false, b and c do not get evaluated.
We also have the option of defining an and-function such that (and-function a b c) evaluates a, b, and c, and returns true when the values are all true. This means that all of a, b, and c get evaluated. and-function has the nice property that you can pass it around as function because it is a function.
There's still one option that seems to be missing: an and-function-delaying-evaluation that returns return if and only if a, b, and c all return true, but that doesn't evaluate, e.g., b and c if a produces false. This can be had, actually, with a function and-funcalling-function that requires its arguments to be a list of functions. For instance:
(define (and-funcalling-function functions)
(or (null? functions)
(and ((car functions))
(and-funcalling-function (cdr functions)))))
(and-funcalling-function
(list (lambda () (even? 2))
(lambda () (odd? 3))))
; => #t
(and-funcalling-function
(list (lambda () (odd? 2))
(lambda () (even? 3)))) ; (even? 3) does not get evaluated
; => #f
Using a macro and this idiom, we can actually implement something with the standard and semantics:
(define-syntax standard-and
(syntax-rules ()
((standard-and form ...)
(and-funcalling-function (list (lambda () form) ...)))))
(macroexpand '(standard-and (odd? 2) (even? 3)))
; =>
; (and-funcalling-function
; (list (lambda () (odd? 2))
; (lambda () (even? 3))))
The lesson to take away from this, of course, is that you can have an and-like function that you can pass around and still get delayed evaluation; you just need to delay evaluation by wrapping things in functions and letting the and-like function call those functions to produce values. (In Scheme, this might be an opportunity to use promises.)

Defining the elements of a list of list as new variables in common lisp

I have a list of lists as follows in Common Lisp of the form
((1 2) (3 4) (5 6))
and which is the value of the variable list, and I want to have three new variables whose values are the elements of the list. For instance:
list-1 (1 2)
list-2 (3 4)
list-3 (5 6)
Is there any function which does this operation?
Use setq, first (or nth and elt) to set:
(setq list-1 (first list)
list-2 (second list)
list-3 (third list))
Or destructuring-bind to bind:
(destructuring-bind (list-1 list-2 list-3) list
...)
Again, destructuring-bind binds the variables instead of assigning them (i.e., it is like let, not like setq).
The notion of binding elements of a list to names of the form list-# can be generalized.
You can create a function to generate a lambda with the ordinal list names as arguments, and a given body:
(defun make-list-lambda (n body)
(let ((list-names (loop for index from 1 to n
collect (intern (format nil "LIST-~D" index)))))
`(lambda ,list-names
(declare (ignorable ,#list-names))
,#body)))
And then create a macro to create the lambda, compile it, and apply it to the list:
(defmacro letlist (list &body body)
(let ((assignments (gensym)))
`(let ((,assignments ,list))
(apply (compile nil (make-list-lambda (length ,assignments) ',body))
,assignments))))
In this way, the assignments are localized to the lambda body:
CL-USER> (letlist '(a b c d e f)
(format t "list-1: ~A~%" list-1)
(format t "list-3: ~A~%" list-3))
list-1: A
list-3: C
NIL
Note: The forms will be compiled every time the macro is invoked, since it will not be known how many list-# arguments will be present until the list is presented!
First set your list to a variable, for instance mylist. Then spit out the required
output using the function format. I'm using CLISP. Hope this helps. This is the actual REPL output.
(setf mylist '((1 2) (3 4) (5 6)) )
((1 2) (3 4) (5 6))
(format t "list-1 ~d~%list-2 ~d~%list-3 ~d" (car mylist)
(second mylist) (last mylist))
list-1 (1 2)
list-2 (3 4)
list-3 ((5 6))
NIL
[142]>
Can someone show me how to get rid of "NIL' in the above output?
I'm new to Lisp. Just learning for fun.

Forming Lisp code to task -- related to flatten list method

I'm having issues trying to form code for a problem I want to resolve. It goes like this:
~ Goal: flatten a nested list into one number
If the object is a list, replace the list with the sum of its atoms.
With nested lists, flatten the innermost lists first and work from there.
Example:
(CONDENSE '(2 3 4 (3 1 1 1) (2 3 (1 2)) 5))
(2 3 4 (6) (2 3 (3)) 5)
(2 3 4 (6) (8) 5)
(28)
=> 28
I've tried to implement the flatten list function for this problem and I ended up with this:
(defun condense (lst)
(cond
((null lst) nil)
((atom lst) (list lst)))
(t (append (flatten (apply #'+ (cdr lst))))))
But it gives me errors :(
Could anyone explain to me what is wrong with my processing/code? How can I improve it?
UPDATE: JUNE 5 2012
(defun condense(lxt)
(typecase lxt
(number (abs lxt))
(list
(if (all-atoms lxt)
(calculate lxt)
(condense (mapcar #'condense lxt))))))
So here, in this code, my true intent is shown. I have a function calculate that performs a calculation based off the values in the list. It is not necessarily the same operation each time. Also, I am aware that I am returning the absolute value of the number; I did this because I couldn't find another way to return the number itself. I need to find a way to return the number if the lxt is a number. And I had it recurse two times at the bottom, because this is one way that it loops on itself infinitely until it computes a single number. NOTE: this function doesn't implement a flatten function anymore nor does it use anything from it.
Imagine you have your function already. What does it get? What must it produce?
Given an atom, what does it return? Given a simple list of atoms, what should it return?
(defun condense (x)
(typecase x
(number
; then what?
(condense-number x))
(list
; then what?
(if (all-atoms x)
(condense-list-of-atoms x) ; how to do that?
(process-further-somehow
(condense-lists-inside x))))
; what other clauses, if any, must be here?
))
What must condense-lists-inside do? According to your description, it is to condense the nested lists inside - each into a number, and leave the atoms intact. So it will leave a list of numbers. To process that further somehow, we already "have" a function, condense-list-of-atoms, right?
Now, how to implement condense-lists-inside? That's easy,
(defun condense-lists-inside (xs)
(mapcar #'dowhat xs))
Do what? Why, condense, of course! Remember, we imagine we have it already. As long as it gets what it's meant to get, it shall produce what it is designed to produce. Namely, given an atom or a list (with possibly nested lists inside), it will produce a number.
So now, fill in the blanks, and simplify. In particular, see whether you really need the all-atoms check.
edit: actually, using typecase was an unfortunate choice, as it treats NIL as LIST. We need to treat NIL differently, to return a "zero value" instead. So it's better to use the usual (cond ((null x) ...) ((numberp x) ...) ((listp x) ...) ... ) construct.
About your new code: you've erred: to process the list of atoms returned after (mapcar #'condense x), we have a function calculate that does that, no need to go so far back as to condense itself. When you substitute calculate there, it will become evident that the check for all-atoms is not needed at all; it was only a pedagogical device, to ease the development of the code. :) It is OK to make superfluous choices when we develop, if we then simplify them away, after we've achieved the goal of correctness!
But, removing the all-atoms check will break your requirement #2. The calculation will then proceed as follows
(CONDENSE '(2 3 4 (3 1 1 1) (2 3 (1 2)) 5))
==
(calculate (mapcar #'condense '(2 3 4 (3 1 1 1) (2 3 (1 2)) 5)))
==
(calculate (list 2 3 4 (condense '(3 1 1 1)) (condense '(2 3 (1 2))) 5))
==
(calculate (list 2 3 4 (calculate '(3 1 1 1))
(calculate (list 2 3 (calculate '(1 2)))) 5))
==
(calculate (list 2 3 4 6 (calculate '(2 3 3)) 5))
==
(calculate (list 2 3 4 6 8 5))
==
28
I.e. it'll proceed in left-to-right fashion instead of the from the deepest-nested level out. Imagining the nested list as a tree (which it is), this would "munch" on the tree from its deepest left corner up and to the right; the code with all-atoms check would proceed strictly by the levels up.
So the final simplified code is:
(defun condense (x)
(if (listp x)
(reduce #'+ (mapcar #'condense x))
(abs x)))
a remark: Looking at that last illustration of reduction sequence, a clear picture emerges - of replacing each node in the argument tree with a calculate application. That is a clear case of folding, just such that is done over a tree instead of a plain list, as reduce is.
This can be directly coded with what's known as "car-cdr recursion", replacing each cons cell with an application of a combining function f on two results of recursive calls into car and cdr components of the cell:
(defun condense (x) (reduce-tree x #'+ 0))
(defun reduce-tree (x f z)
(labels ((g (x)
(cond
((consp x) (funcall f (g (car x)) (g (cdr x))))
((numberp x) x)
((null x) z)
(T (error "not a number")))))
(g x)))
As you can see this version is highly recursive, which is not that good.
Is this homework? If so, please mark it as such. Some hints:
are you sure the 'condensation' of the empty list in nil? (maybe you should return a number?)
are you sure the condensation of one element is a list? (maybe you should return a number?)
are you sure the condensation of the last case is a list? (shouldn't you return a number)?
In short, how is your condense ever going to return 28 if all your returned values are lists?
Task: With nested lists, flatten the innermost lists first and work from there
sum
flatten lists
For sum use REDUCE, not APPLY.
For flatten lists you need a loop. Lisp already provides specialized mapping functions.
Slightly more advanced: both the sum and the flatten can be done by a call to REDUCE.
You can also write down the recursion without using a higher-order function like APPLY, REDUCE, ... That's a bit more work.
Here's added the explanation of the errors you were having, actually you were close to solving your problem, just a bit more effort and you would get it right.
; compiling (DEFUN CONDENSE ...)
; file: /tmp/file8dCll3
; in: DEFUN CONDENSE
; (T (APPEND (FLATTEN (APPLY #'+ (CDR LST)))))
;
; caught WARNING:
; The function T is undefined, and its name is reserved
; by ANSI CL so that even
; if it were defined later, the code doing so would not be portable.
;
; compilation unit finished
; Undefined function:
; T
; caught 1 WARNING condition
;STYLE-WARNING: redefining CONDENSE in DEFUN
(defun condense (lst)
(cond
((null lst) nil)
((atom lst) (list lst)))
;.------- this is a function call, not a condition
;| (you closed the parens too early)
(t (append (flatten (apply #'+ (cdr lst))))))
;; Argument Y is not a NUMBER: (3 1 1 1)
;; [Condition of type SIMPLE-TYPE-ERROR]
(defun condense (lst)
(cond
((null lst) nil)
((atom lst) (list lst)); .-- not a number!
;You are calling #'+ -------. |
;on something, which | '(3 4 (3 1 1 1) (2 3 (1 2)) 5)
; is not a number. | |
(t (append (flatten (apply #'+ (cdr lst)))))))
;; You probably wanted to flatten first, and then sum
(defun condense (lst)
(cond
((null lst) nil); .--- returns just the
((atom lst) (list lst)); / atom 28, you can
; .---------------------/ just remove it.
(t (append (apply #'+ (flatten lst))))))
;; Now, you are lucky that append would just return the
;; atom if it's not a list
(defun condense (lst)
(cond
((null lst) nil)
((atom lst) (list lst))
(t (apply #'+ (flatten lst)))))
;; Again, you are lucky because (apply can take enough arguments
;; while your list is reasonably small - this will not always be
;; the case, that is why you need to use something more durable,
;; for example, reduce.
(defun condense (lst)
(cond
((null lst) nil)
((atom lst) (list lst))
(t (reduce #'+ (flatten lst)))))
;; Whoa!
(condense '(2 3 4 (3 1 1 1) (2 3 (1 2)) 5))
This is all given the flatten function actually works.
If your lisp already implements flatten and reduce functions (such as Clojure, which I will use here), you can just do something like:
user=> (defn condense [l] (reduce + 0 (flatten l)))
#'user/condense
user=> (condense [1 [2 [[3 4] 5]]])
15
user=>
Failing that, a naive implementation of those functions might be:
(defn flatten [l]
(cond (nil? l) l
(coll? l) (let [[h & t] l]
(concat (flatten h) (flatten t)))
true [l]))
and:
(defn reduce [op initial-value [h & t]]
(if (nil? t)
(op initial-value h)
(op initial-value (reduce op h t))))
But make sure to check the semantics of the particular Lisp you are using. Also, if you are implementing reduce and flatten, you may want to make them tail recursive which I didn't so as to maintain clarity.
In Common Lisp you would do something like:
(defun flatten (l)
(cond ((null l) l)
((atom l) (list l))
(t (append (flatten (car l))
(flatten (cdr l))))))
and use apply instead of reduce:
(defun condense (l) (apply #'+ (flatten l)))

LISP disposing of pesky NILs

I have the following filter function that filters out a list, x, that doesn't satisfy the function f.
For example, I call (filter 'evenp '(0 1 2 3)) and get back (NIL 1 NIL 3). But this is exactly my problem. How do I make it so that I just get back (1 3) ?
(defun filter (f x)
(setq h (mapcar #'(lambda (x1)
(funcall f x1))
x))
(mapcar #'(lambda (a b)
(cond ((null a) b)))
h x))
i.e. the problem is right here: (lambda (a b) (cond ( (null a) b) ) ) In my cond I don't have a t , or else statement, so shouldn't it just stop right there and not return nil ? How do I make it "return" nothing, not even nil, if the (cond ( (null a) b) ) isn't satisfied?
Much appreciated. :)
Based on this question it would be:
(remove-if #'evenp '(0 1 2 3))
Ignoring the other questions raised by this post, I'll say that mapcar will always return something for each thing it's mapping over, so you can't use another mapcar to clean up the NILs there. This is what mapcar does -- it walks over the item (or items, if mapping on multiple lists, as your second attempted mapcar does) and collects the result of calling some function on those arguments.
Instead, in this situation, if you had to use mapcar for some reason, and didn't want the NILs, you could use the remove function, i.e. (remove nil (mapcar ...))
Since #stark's answer is posted above, I'll say that the remove-if function there is essentially what you're trying to implement here. (That's where the question of whether or not this is for homework becomes most relevant.)
To answer the more general question of how to splice an arbitrary number of items (including none at all) into the result, mapcan (which is semantically mapcar + append) is useful for that:
(defun filter (f xs)
(mapcan (lambda (x)
(if (funcall f x)
(list x)
nil))
xs))
mapcan is also useful when you want to map an item to multiple results:
(defun multi-numbers (xs)
(mapcan (lambda (x) (list x (+ x x) (* x x))) xs))
(multi-numbers (list 1 2 3))
;=> (1 2 1 2 4 4 3 6 9)