Here is my problem:Without using MEMBER, complete the following definition of a recursive function POS
such that if L is a list and E is an element of L then (POS E L) returns the position of the first
occurrence of E in L, and such that if E is not an element of L then (POS E L) returns 0.This is the solution have come up with:
(DEFUN POS (E L)
(COND ((ENDP L) 0)
((EQUAL E (CAR L)) 1 )
(T
(+ 1 (POS E (CDR L)) )
)))
The algorithm works fine if the element I am looking for is in the list. My problem is that when the element is not in the list I will get the length of the list.
Example:
list[1,2,3,4] Find: 5 will reurn 4
How do I get it to return 0 if element is not found. And as it is functional programming I can't use loops or variable.
You always return (+ 1 <recursive-call>). But what if the recursive result is zero? You should check that return value before computing the result.
if you find an occurence, return 1
if you don't find a result, compute recursively, which gives you R
if R is zero, return zero
otherwise, return R + 1
As an aside, the Common Lisp way would be:
(or (position E L :test #'equal) 0)
As #coredump has explained, the problem is that you are always adding 1 to the result, even if you haven't found the element. I would keep the track of the current position within the list by adding an extra parameter to function POS:
(defun pos (element list &optional (start 0))
(cond ((endp list) 0)
((equal element (first list)) (1+ start))
(t (pos element (rest list) (1+ start)))))
Testing:
(pos 'a '(b a c d a))
2
(pos 'a '(a d a f g))
1
(pos 'w '(a b c d e f))
0
One extra benefit: this function generates iterative process due to recursive call being in tail-call position (however, ANSI Common Lisp does not guarantee it will do tail-call optimization! AFAIK, CLisp doesn't do it; SBCL and CCL will do for optimized code, see DECLARE). More idiomatic Common Lisp solution would be using LOOP:
(defun pos (element list)
(loop for x in list
counting x into pos
when (equal element x)
return pos
end
finally (return 0)))
Related
In order to understand functional programing, please help me to write a function that output nth element of a list,
Allowed command:
define lambda cond else empty empty? first rest cons list
list? = equal? and or not + - * / < <= > >=
Sample output:
(fourth-element '(a b c d e)) => d
(fourth-element '(x (y z) w h j)) => h
(fourth-element '((a b) (c d) (e f) (g h) (i j))) => (list 'g 'h)
or ‘(g h)
(fourth-element '(a b c)) => empty
I could write this in python, but I am not family with racket syntax,
def element(lst, x=0):
counter = x;
if (counter >= 3):
return lst[0]
else:
return element(lst[1:],x+1)
a = [1,2,3,4,5,6]
print(element(a))
The Output is 4
Comparing with code above in python. What is equivalent behavior in function that create local variable counter. What is "keyword" for return
It looks like you came up with an answer of your own. Nice work! I would recommend a more generic nth procedure that takes a counter as an argument. This allows you to get any element in the input list
(define (nth lst counter)
(cond ((null? lst) (error 'nth "index out of bounds"))
((= counter 0) (first lst))
(else (nth (rest lst) (- counter 1)))))
Now if you want a procedure that only returns the 4th element, we create a new procedure which specializes the generic nth
(define (fourth-element lst)
(nth lst 3))
That's it. Now we test them out with your inputs
(define a `(1 2 3 (4 5) 7))
(define b `(1 2 3))
(define c `((a b)(c d)(e f)(g h)(i j)))
(define d `(a b c))
(fourth-element a) ; '(4 5)
(fourth-element b) ; nth: index out of bounds
(fourth-element c) ; '(g h)
(fourth-element d) ; nth: index out of bounds
Note, when the counter goes out of bounds, I chose to raise an error instead of returning a value ("empty") like your program does. Returning a value makes it impossible to know whether you actually found a value in the list, or if the default was returned. In the example below, notice how your procedure cannot differentiate the two inputs
(define d `(a b c))
(define e `(a b c ,"empty"))
; your implementation
(fourth-element e) ; "empty"
(fourth-element d) ; "empty"
; my implementation
(fourth-element e) ; "empty"
(fourth-element d) ; error: nth: index out of bounds
If you don't want to throw an error, there's another way we can encode nth. Instead of returning nth element, we can return the nth pair whose head contains the element in question.
Below, nth always returns a list. If the list is empty, no element was found. Otherwise, the nth element is the first element in the result.
(define (nth lst counter)
(cond ((null? lst) '())
((= counter 0) lst)
(else (nth (rest lst) (- counter 1)))))
(define (fourth-element lst)
(nth lst 3))
(define a `(1 2 3 (4 5) 7))
(define b `(1 2 3))
(define c `((a b)(c d)(e f)(g h)(i j)))
(define d `(a b c))
(define e `(a b c ,"empty"))
(fourth-element a) ; '((4 5) 7)
(fourth-element b) ; '()
(fourth-element c) ; '((g h) (i j))
(fourth-element d) ; '()
(fourth-element e) ; '("empty")
Hopefully this gets you to start thinking about domain (procedure input type) and codomain (procedure output type).
In general, you want to design procedures that have natural descriptions like:
" nth takes a list and a number and always returns a list" (best)
" nth takes a list and a number and returns an element of the list or raises an exception if the element is not found" (good, but now you must handle errors)
Avoid procedures like
" nth takes a list and a number and returns an element of the list or a string literal "empty" if the element is not found" (unclear codomain)
By thinking about your procedure's domain and codomain, you have awareness of how your function will work as it's inserted in various parts of your program. Using many procedures with poorly-defined domains lead to disastrous spaghetti code. Conversely, well-defined procedures can be assembled like building blocks with little (or no) glue code necessary.
Here is how to write it in Python:
def nth(lst, idx=0):
if (len(lst) == 0):
return "empty"
elif (idx == 0):
return lst[0]
else:
return nth(lst[1:], idx - 1)
nth([1,2,3], 1)
# ==> 2
def fourth-element(lst):
return nth(lst, 4)
Same in Scheme/Racket:
(define (nth lst idx)
(cond ((empty? lst) empty) ; more effiecent than (= (length lst) 0)
((= idx 0) (first lst))
(else (nth (rest lst) (- idx 1))))
(nth '(1 2 3) 1)
; ==> 2
(define (fourth-element lst)
(nth lst 4))
There is no keyword for return. Every form returns the last evaluated code:
(if (< 4 x)
(bar x)
(begin
(display "print this")
(foo x)))
This if returns either the result of (bar x) or it prints "print this" then returns the result of (foo x). The reason is that for the two outcomes of the if they are the tail expressions.
(define (test x)
(+ x 5)
(- x 3))
This function has two expressions. The first is dead code since it has no side effect and since it's not a tail expression, but the (- x 3) is what this function returns.
(define (test x y)
(define xs (square x))
(define ys (square y))
(sqrt (+ xs ys)))
This has 3 expressions. The first two has side effects that it binds two local variables while the third uses this to compute the returned value.
(define a `(1 2 3 (4 5) 7))
(define b `(1 2 3))
(define c `((a b)(c d)(e f)(g h)(i j)))
(define d `(a b c))
(define (my-lst-ref lst counter)
(cond[(>= counter 3) (first lst)]
[else (my-lst-ref (rest lst)(+ counter 1))]
)
)
(define (fourth-element lst)
(cond[(>= (list-length lst) 4) (my-lst-ref lst 0)]
[else "empty"]))
(fourth-element a)
(fourth-element c)
(fourth-element d)
Output:
(list 4 5)
(list 'g 'h)
"empty"
I am new to Scheme and I have some questions.
First I want to make a graph and after that to use it for some stuff (like Dijkstra and etc.) First I wanted to make a function that returns what is the count of the Vertexes (not sure if that is a word). But I get this error and I just can't realise what is it and why I am getting it.
Also when I get the number of the vertexes I want to make a list with pairs every pair will give me information for a given vertex but I don't know how to do it.
(example if there are 4 vertexes the list should be ((0,-1) (0 -1) (0 -1) (0 -1)) "-1" will be like infinity since there will be no "weights" under 0 )
I am sure there are 1182498 better ways to do the algorithm but I would like to try with my idea. But still I don't have enough experience with Scheme.
Here is my code with the error:
(define G '((A (B 6) (E 5))
(B (D 3))
(C (A 1) (D 1))
(D (C 7) (E 5) (W 3))
(E (D 4) (F 10))
(F)
))
(define (getNumV G)
(if (null? (car G)) 0)
(+ 1 (getNumV (cdr G))))
You cannot use car if the list is empty, so the test is simply (null? G), not (null? (car G)).
Also, you have a closing parenthesis after the 0 which is wrong, both with regards to logic and because in Scheme an if is required to have an else part (you can use when or unless to avoid this).
So the code should be
(define (getNumV G)
(if (null? G)
0
(+ 1 (getNumV (cdr G)))))
so that
(display (getNumV G))
=> 6
Also, try to indent your code properly, and to have no dangling closing parentheses.
It would be cleaner to use a generic name for the list parameter of your procedure such as lst, not the name of the real list G:
(define (getNumV lst)
(if (null? lst)
0
(+ 1 (getNumV (cdr lst)))))
(display (getNumV G))
=> 6
Note that you can use the build-in procedure length instead of your getNumV:
(display (length G))
=> 6
I want to make a function that checks if an element is a member of a list. The list can contain other lists.
This is what I came with so far:
(defun subl(l)
(if (numberp l)
(if (= l 10)
(princ "Found"))
(mapcar 'subl l)))
Now the number I am searching for is hard-coded and it is 10. I would like to write it somehow so the function takes another parameter(the number I am searching for) and returns true or 1 when it finds it. The main problem is that I can't see a way to control mapcar. mapcar executes subl on each element of l, if l si a list. But how can I controll the returned values of each call?
I would like to check the return value of each subl call and if one of it is true or 1 to return true or 1 till the last recursive call. So in the end subl returns true or one if the element is contained in the list or nil otherwise.
Any idea?
This procedure below should process as you have described;
(defun member-nested (el l)"whether el is a member of l, el can be atom or cons,
l can be list of atoms or not"
(cond
((null l) nil)
((equal el (car l)) t)
((consp (car l)) (or (member-nested el (car l))
(member-nested el (cdr l))))
(t (member-nested el (cdr l)))))
mapcar is a very generic primitive to map a function over a list. You can use one of the built-in combinators which are much more closely suited with what you're trying to do. Look into the member function.
Your function seems to play the role of main function and helper at the same time. That makes your code a lot more difficult to understand than it has to be..
So imagine you split the two:
;; a predicate to check if an element is 10
(defun number10p (l)
(and (numberp l)
(= l 10)))
;; the utility function to search for 10 amongst elements
(defun sublistp (haystack)
(mapcar #'number10p haystack)))
But here when you do (sublistp '(5 10 15 20)) you'll get (nil t nil nil) back. Thats because mapcar makes a list of every result. For me it seems you are describing some since it stops at the first true value.
(defun sublistp (haystack)
(some #'number10p haystack)))
(sublistp '(5 10 15 20)) ; ==> t
Now to make it work for any data type we change the predicate and make it as a local function where we have the argument we are searching for:
(defun sublistp (needle haystack)
(flet ((needlep (x)
(equal x needle)))
(some #'needlep haystack)))
(sublistp '(a b) '(a b c (a b) d e f)) ; ==> t
You can also do this with an anonymous predicate like this:
(defun sublistp (needle haystack)
(some #'(lambda (x)
(equal x needle))
haystack))
An implementation of this is the member function, except it returns the match as truth value. That's ok since anything but nil is true in CL:
(member 10 '(5 10 15 20)) ; ==> (10 15 20)
EDIT
You commented on a different answer that you are required to use mapcar in that case use it together with append to get a list of all matches and check if the list has greater than 0 elements:
(defun sublistp (needle haystack)
(flet ((needle-check (x)
(if (equal x needle) '(t) nil)))
(< 0 (length
(apply #'append
(mapcar #'needle-check haystack))))))
How it works is that for each match you get a list of one element and for every non match you get an empty list. When appending the lists you'll get the empty list when there is not match. For all other results you have a match. This is not a very efficient implementation.
I am trying to implement a macro which expands a unlimited list of triplet-arguments into lambda-function to check an argument (object).
e.g.
(where >= amount 5 equalp name "george")
=>
#'(lambda (arg)
(and
(>= (amount arg) 5)
(equalp (name arg) "george")))
I got quite close with this macrodefinition:
(defmacro where (&rest list-of-argument-triplets )
`#'(lambda (arg)
(and
,(do ( (counter 0 (+ counter 3)) (liste (list)))
( (>= counter (list-length list.of-argument-triplets)) liste)
(push `( ,(nth counter list-of-argument-triplets)
( ,(nth (+ counter 1) list-of-argument-triplets) arg)
,(nth (+ counter 2) list-of-argument-triplets)
liste)))))
but this expands to
#'(lambda (arg)
(and ((>= (amount arg) 5)
(equalp (name arg) "george"))))
which is one parentheses after the "and" too much. As a conclusion I would have to use an # in front of the result-form, but then the "#list" is treated
as if it is an parameter-name, and therefore I get an no-value error, instead of an expanded list.
*** - RETURN-FROM: variable #LISTE has no value
How can I fix that?
Code smell: you use NTH to access elements of a list.
I would first define a helper function, which makes out of the flat list a list of three element lists:
(defun triplets (list)
(loop while list
collect (list (pop list)
(pop list)
(pop list))))
CL-USER 1 > (triplets '(a b c d e f g h i))
((A B C) (D E F) (G H I))
The macro is then slightly simpler to write:
(defmacro where (&rest flat-triplets)
`#'(lambda (arg)
(and
,#(mapcar (lambda (triplet)
(destructuring-bind (fn accessor item)
triplet
`(,fn (,accessor arg) ,item)))
(triplets flat-triplets))))
CL-USER 2 > (macroexpand-1 '(where >= amount 5 equalp name "george"))
(FUNCTION (LAMBDA (ARG) (AND (>= (AMOUNT ARG) 5) (EQUALP (NAME ARG) "george"))))
T
I'm trying to solve a problem in Scheme which is demanding me to use a nested loop or a nested recursion.
e.g. I have two lists which I have to check a condition on their Cartesian product.
What is the best way to approach these types of problems? Any pointers on how to simplify these types of functions?
I'll elaborate a bit, since my intent might not be clear enough.
A regular recursive function might look like this:
(define (factorial n)
(factorial-impl n 1))
(define (factorial-impl n t)
(if (eq? n 0)
t
(factorial-impl (- n 1) (* t n))))
Trying to write a similar function but with nested recursion introduces a new level of complexity to the code, and I was wondering what the basic pattern is for these types of functions, as it can get very ugly, very fast.
As a specific example, I'm looking for the easiest way to visit all the items in a cartesian product of two lists.
In Scheme,
The "map" function is often handy for computing one list based on another.
In fact, in scheme, map takes an "n-argument" function and "n" lists and calls the
function for each corresponding element of each list:
> (map * '(3 4 5) '(1 2 3))
(3 8 15)
But a very natural addition to this would be a "cartesian-map" function, which would call your "n-argument" function with all of the different ways of picking one element from each list. It took me a while to figure out exactly how to do it, but here you go:
; curry takes:
; * a p-argument function AND
; * n actual arguments,
; and returns a function requiring only (p-n) arguments
; where the first "n" arguments are already bound. A simple
; example
; (define add1 (curry + 1))
; (add1 3)
; => 4
; Many other languages implicitly "curry" whenever you call
; a function with not enough arguments.
(define curry
(lambda (f . c) (lambda x (apply f (append c x)))))
; take a list of tuples and an element, return another list
; with that element stitched on to each of the tuples:
; e.g.
; > (stitch '(1 2 3) 4)
; ((4 . 1) (4 . 2) (4 . 3))
(define stitch
(lambda (tuples element)
(map (curry cons element) tuples)))
; Flatten takes a list of lists and produces a single list
; e.g.
; > (flatten '((1 2) (3 4)))
; (1 2 3 4)
(define flatten
(curry apply append))
; cartesian takes two lists and returns their cartesian product
; e.g.
; > (cartesian '(1 2 3) '(4 5))
; ((1 . 4) (1 . 5) (2 . 4) (2 . 5) (3 . 4) (3 . 5))
(define cartesian
(lambda (l1 l2)
(flatten (map (curry stitch l2) l1))))
; cartesian-lists takes a list of lists
; and returns a single list containing the cartesian product of all of the lists.
; We start with a list containing a single 'nil', so that we create a
; "list of lists" rather than a list of "tuples".
; The other interesting function we use here is "fold-right" (sometimes called
; "foldr" or "reduce" in other implementations). It can be used
; to collapse a list from right to left using some binary operation and an
; initial value.
; e.g.
; (fold-right cons '() '(1 2 3))
; is equivalent to
; ((cons 1 (cons 2 (cons 3 '())))
; In our case, we have a list of lists, and our binary operation is to get the
; "cartesian product" between each list.
(define cartesian-lists
(lambda (lists)
(fold-right cartesian '(()) lists)))
; cartesian-map takes a n-argument function and n lists
; and returns a single list containing the result of calling that
; n-argument function for each combination of elements in the list:
; > (cartesian-map list '(a b) '(c d e) '(f g))
; ((a c f) (a c g) (a d f) (a d g) (a e f) (a e g) (b c f)
; (b c g) (b d f) (b d g) (b e f) (b e g))
(define cartesian-map
(lambda (f . lists)
(map (curry apply f) (cartesian-lists lists))))
Without all the comments and some more compact function definition syntax we have:
(define (curry f . c) (lambda x (apply f (append c x))))
(define (stitch tuples element)
(map (curry cons element) tuples))
(define flatten (curry apply append))
(define (cartesian l1 l2)
(flatten (map (curry stitch l2) l1)))
(define cartesian-lists (curry fold-right cartesian '(()))))
(define (cartesian-map f . lists)
(map (curry apply f) (cartesian-lists lists)))
I thought the above was reasonably "elegant"... until someone showed me the equivalent Haskell definition:
cartes f (a:b:[]) = [ f x y | x <- a , y <- b ]
cartes f (a:b:bs) = cartes f ([ f x y | x <- a , y <- b ]:bs)
2 lines!!!
I am not so confident on the efficiency of my implementation - particularly the "flatten" step was quick to write but could end up calling "append"
with a very large number of lists, which may or may not be very efficient on some Scheme
implementations.
For ultimate practicality/usefulness you would want a version that could take "lazily evaluated" lists/streams/iterator rather than fully specified lists.... a "cartesian-map-stream" function if you like, that would then return a "stream" of the results... but this depends on the context (I am thinking of the "stream" concept as introduced in SICP)... and would come for free from the Haskell version thanks to it's lazy evaluation.
In general, in Scheme, if you wanted to "break out" of the looping at some point you could also use a continuation (like throwing an exception but it is accepted practise in Scheme for control flow).
I had fun writing this!
I'm not sure I see what the problem is.
I believe the main thing you have to understand in functional programming is : build complicated functions by composing several simpler functions.
For instance, in this case:
;compute the list of the (x,y) for y in l
(define (pairs x l)
(define (aux accu x l)
(if (null? l)
accu
(let ((y (car l))
(tail (cdr l)))
(aux (cons (cons x y) accu) x tail))))
(aux '() x l))
(define (cartesian-product l m)
(define (aux accu l)
(if (null? l)
accu
(let ((x (car l))
(tail (cdr l)))
(aux (append (pairs x m) accu) tail))))
(aux '() l))
You identify the different steps: to get the cartesian product, if you "loop" over the first list, you're going to have to be able to compute the list of the (x,y), for y in the second list.
There are some good answers here already, but for simple nested functions (like your tail-recursive factorial), I prefer a named let:
(define factorial
(lambda (n)
(let factorial-impl ([n n] [t 1])
(if (eq? n 0)
t
(factorial-impl (- n 1) (* t n))))))