I have a scheme function where I have a list and I am trying to put the numbers into a Binary Search Tree one by one. However, I keep getting "unspecified return value"
(define (insertB L)
(if (not (null? L))
(begin (let() BST (insert (car L) BST))
(insertB (cdr L))
)
)
)
I know my insert function works for a single number. But I need to get insertB to work for a list.
Try this:
(define (insertB BST L)
(if (null? L)
BST
(insertB (insert (car L) BST)
(cdr L))))
It's better if we pass BST along as a parameter, instead of using a global definition. Other than that, you have to make sure of returning the modified tree when we finish traversing the list (base case). Also notice how at each recursive call we insert the current element in the tree and pass it along, and at the same time we go to the next element in the list. If higher-order procedures are allowed, we can write a simpler, equivalent solution:
(define (insertB BST L)
(foldr insert BST L))
Can you generalize the BST parameter like this?
(define (insertB L BST)
(if (not (null? L))
(insertB (cdr L) (insert (car L) BST))
BST
)
)
Or the equivalent:
(define (insertB L BST)
(if (null? L)
BST
(insertB (cdr L) (insert (car L) BST))
)
)
I think it's easier to understand. It's also more general.
Related
This function is supposed to take a list (full of strings or ints, which is why it starts with that 'if' statement) and check to see if it is in ascending order.
I haven't been able to figure out how to keep it from crashing, as on the last recursive call, the 'cadr' has nothing to pull from, as the 'car' is the final element.
(define (my-sorted? lst)
(if (number? (car lst))
(if (< (car lst) (cadr lst))
(my-sorted? (rest lst))
#f)
#f)
)
I know that the sorted function exists, but I need to implement this function recursively.
Thanks for any help.
The two most basic lists that you should try are:
(my-sorted? '()) ; ==> #t (empty list is always sorted)
(my-sorted? '(1)) ; ==> #t (one element list is always sorted)
Your current code just does car and cadr on its argument so it will fail at different levels with these two tests.
The there is how to compare a number and something which is not a number. < expects both arguments to be numbers, but your list can be both strings and numbers. What is smaller of "x" and 7? You cannot do (< 7 "x").
Instead of nesting if you might consider cond which is lisps way of doing if-elseif-else. Basically you can do your code with cond like this:
(cond
((not (number? (car lst))) #f)
((< (car lst) (cadr lst)) (my-sorted? (rest lst))
(else #f))
EDIT
Since the list should either be all elements as string or all as number you simply can just determine the comparison function by looking at the first element and do your recursion with a named let and reuse the one based on the first element.
(define (my-sorted lst)
;; determine what comparison function to use, bind it to greater?
(define greater?
(if (and (pair? lst) (number? (car lst)))
>
string>?))
;; main recursive loop uses that one function
;; this can be done with define + call as well
(let loop ((lst lst))
(cond ((or (null? lst) (null? (cdr lst))) ...)
((greater? (car lst) (cadr lst)) ...)
(else (loop ...)))))
I'm totally new to Scheme and I am trying to implement my own map function. I've tried to find it online, however all the questions I encountered were about some complex versions of map function (such as mapping functions that take two lists as an input).
The best answer I've managed to find is here: (For-each and map in Scheme). Here is the code from this question:
(define (map func lst)
(let recur ((rest lst))
(if (null? rest)
'()
(cons (func (car rest)) (recur (cdr rest))))))
It doesn't solve my problem though because of the usage of an obscure function recur. It doesn't make sense to me.
My code looks like this:
(define (mymap f L)
(cond ((null? L) '())
(f (car L))
(else (mymap (f (cdr L))))))
I do understand the logic behind the functional approach when programming in this language, however I've been having great difficulties with coding it.
The first code snippet you posted is indeed one way to implement the map function. It uses a named let. See my comment on an URL on how it works. It basically is an abstraction over a recursive function. If you were to write a function that prints all numbers from 10 to 0 you could write it liks this
(define (printer x)
(display x)
(if (> x 0)
(printer (- x 1))))
and then call it:
(printer 10)
But, since its just a loop you could write it using a named let:
(let loop ((x 10))
(display x)
(if (> x 0)
(loop (- x 1))))
This named let is, as Alexis King pointed out, syntactic sugar for a lambda that is immediately called. The above construct is equivalent to the snippet shown below.
(letrec ((loop (lambda (x)
(display x)
(if (> x 0)
(loop (- x 1))))))
(loop 10))
In spite of being a letrec it's not really special. It allows for the expression (the lambda, in this case) to call itself. This way you can do recursion. More on letrec and let here.
Now for the map function you wrote, you are almost there. There is an issue with your two last cases. If the list is not empty you want to take the first element, apply your function to it and then apply the function to the rest of the list. I think you misunderstand what you actually have written down. Ill elaborate.
Recall that a conditional clause is formed like this:
(cond (test1? consequence)
(test2? consequence2)
(else elsebody))
You have any number of tests with an obligatory consequence. Your evaluator will execute test1? and if that evaluated to #t it will execute the consequence as the result of the entire conditional. If test1? and test2? fail it will execute elsebody.
Sidenote
Everything in Scheme is truthy except for #f (false). For example:
(if (lambda (x) x)
1
2)
This if test will evaluate to 1 because the if test will check if (lambda (x) x) is truthy, which it is. It is a lambda. Truthy values are values that will evaluate to true in an expression where truth values are expected (e.g., if and cond).
Now for your cond. The first case of your cond will test if L is null. If that is evaluated to #t, you return the empty list. That is indeed correct. Mapping something over the empty list is just the empty list.
The second case ((f (car L))) literally states "if f is true, then return the car of L".
The else case states "otherwise, return the result mymap on the rest of my list L".
What I think you really want to do is use an if test. If the list is empty, return the empty list. If it is not empty, apply the function to the first element of the list. Map the function over the rest of the list, and then add the result of applying the function the first element of the list to that result.
(define (mymap f L)
(cond ((null? L) '())
(f (car L))
(else (mymap (f (cdr L))))))
So what you want might look look this:
(define (mymap f L)
(cond ((null? L) '())
(else
(cons (f (car L))
(mymap f (cdr L))))))
Using an if:
(define (mymap f L)
(if (null? L) '()
(cons (f (car L))
(mymap f (cdr L)))))
Since you are new to Scheme this function will do just fine. Try and understand it. However, there are better and faster ways to implement this kind of functions. Read this page to understand things like accumulator functions and tail recursion. I will not go in to detail about everything here since its 1) not the question and 2) might be information overload.
If you're taking on implementing your own list procedures, you should probably make sure they're using a proper tail call, when possible
(define (map f xs)
(define (loop xs ys)
(if (empty? xs)
ys
(loop (cdr xs) (cons (f (car xs)) ys))))
(loop (reverse xs) empty))
(map (λ (x) (* x 10)) '(1 2 3 4 5))
; => '(10 20 30 40 50)
Or you can make this a little sweeter with the named let expression, as seen in your original code. This one, however, uses a proper tail call
(define (map f xs)
(let loop ([xs (reverse xs)] [ys empty])
(if (empty? xs)
ys
(loop (cdr xs) (cons (f (car xs)) ys)))))
(map (λ (x) (* x 10)) '(1 2 3 4 5))
; => '(10 20 30 40 50)
Can someone explain to me how the recursion works in the following function? Specifically, I am interested in what happens when the function reaches its base case. Also, why is a named let used in this code? (I am not familiar with named lets)
(define (unzip list-of-pairs)
(if (null? list-of-pairs)
(cons '() '())
(let ((unzipped (unzip (cdr list-of-pairs))))
(cons (cons (car (car list-of-pairs)) (car unzipped))
(cons (cdr (car list-of-pairs)) (cdr unzipped))))))
The procedure shown doesn't have anything special about it, you're just iterating over a list of this form:
'((1 . 2) (3 . 4) (5 . 6))
The only "weird" part is that the output is building two lists instead of the usual single list. As you know, when we're building a single list as output the base case is this:
(if (null? lst) '() ...)
But here, given that we're simultaneously building two lists, the base case looks like this:
(if (null? lst) (cons '() '()) ...)
The code in the question is not using a named let, it's just a plain old garden-variety let, there's nothing special about it. It's useful because we want to call the recursion only once, given that we need to obtain two values from the recursive call.
If we don't mind being inefficient, the procedure can be written without using let, at the cost of calling the recursion two times at each step:
(define (unzip list-of-pairs)
(if (null? list-of-pairs)
(cons '() '())
(cons (cons (car (car list-of-pairs))
(car (unzip (cdr list-of-pairs))))
(cons (cdr (car list-of-pairs))
(cdr (unzip (cdr list-of-pairs)))))))
Of course, the advantage of using let is that it avoids the double recursive call.
So i started learning Lisp yesterday and started doing some problems.
Something I'm having a hard time doing is inserting/deleting atoms in a list while keeping the list the same ex: (delete 'b '(g a (b) l)) will give me (g a () l).
Also something I'm having trouble with is this problem.
I'm suppose to check if anywhere in the list the atom exist.
I traced through it and it says it returns T at one point, but then gets overriden by a nil.
Can you guys help :)?
I'm using (appear-anywhere 'a '((b c) g ((a))))
at the 4th function call it returns T but then becomes nil.
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T (appear-anywhere a (car l))(appear-anywhere a (cdr l)))))
Let's look at one obvious problem:
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T (appear-anywhere a (car l))(appear-anywhere a (cdr l)))))
Think about the last line of above.
Let's format it slightly differently.
(defun appear-anywhere (a l)
(cond
((null l) nil)
((atom (car l))
(cond
((equal (car l) a) T)
(T (appear-anywhere a (cdr l)))))
(T
(appear-anywhere a (car l))
(appear-anywhere a (cdr l)))))
The last three lines: So as a default (that's why the T is there) the last two forms will be computed. First the first one and then the second one. The value of the first form is never used or returned.
That's probably not what you want.
Currently your code just returns something when the value of a appears anywhere in the rest of the list. The first form is never really used.
Hint: What is the right logical connector?
My task is to write function in lisp which finds maximum of a list given as argument of the function, by using recursion.I've tried but i have some errors.I'm new in Lisp and i am using cusp plugin for eclipse.This is my code:
(defun maximum (l)
(if (eq((length l) 1)) (car l)
(if (> (car l) (max(cdr l)))
(car l)
(max (cdr l))
))
If this isn't a homework question, you should prefer something like this:
(defun maximum (list)
(loop for element in list maximizing element))
Or even:
(defun maximum (list)
(reduce #'max list))
(Both behave differently for empty lists, though)
If you really need a recursive solution, you should try to make your function more efficient, and/or tail recursive. Take a look at Diego's and Vatine's answers for a much more idiomatic and efficient recursive implementation.
Now, about your code:
It's pretty wrong on the "Lisp side", even though you seem to have an idea as to how to solve the problem at hand. I doubt that you spent much time trying to learn lisp fundamentals. The parentheses are messed up -- There is a closing parenthesis missing, and in ((length l) 1), you should note that the first element in an evaluated list will be used as an operator. Also, you do not really recurse, because you're trying to call max (not maximize). Finally, don't use #'eq for numeric comparison. Also, your code will be much more readable (not only for others), if you format and indent it in the conventional way.
You really should consider spending some time with a basic Lisp tutorial, since your question clearly shows lack of understanding even the most basic things about Lisp, like the evaluation rules.
I see no answers truly recursive and I've written one just to practice Common-Lisp (currently learning). The previous answer that included a recursive version was inefficient, as it calls twice maximum recursively. You can write something like this:
(defun my-max (lst)
(labels ((rec-max (lst actual-max)
(if (null lst)
actual-max
(let ((new-max (if (> (car lst) actual-max) (car lst) actual-max)))
(rec-max (cdr lst) new-max)))))
(when lst (rec-max (cdr lst) (car lst)))))
This is (tail) recursive and O(n).
I think your problem lies in the fact that you refer to max instead of maximum, which is the actual function name.
This code behaves correctly:
(defun maximum (l)
(if (= (length l) 1)
(car l)
(if (> (car l) (maximum (cdr l)))
(car l)
(maximum (cdr l)))))
As written, that code implies some interesting inefficiencies (it doesn't have them, because you're calling cl:max instead of recursively calling your own function).
Function calls in Common Lisp are typically not memoized, so if you're calling your maximum on a long list, you'll end up with exponential run-time.
There are a few things you can do, to improve the performance.
The first thing is to carry the maximum with you, down the recursion, relying on having it returned to you.
The second is to never use the idiom (= (length list) 1). That is O(n) in list-length, but equivalent to (null (cdr list)) in the case of true lists and the latter is O(1).
The third is to use local variables. In Common Lisp, they're typically introduced by let. If you'd done something like:
(let ((tail-max (maximum (cdr l))))
(if (> (car l) tail-max)
(car l)
tail-max))
You would've had instantly gone from exponential to, I believe, quadratic. If in combination had done the (null (cdr l)) thing, you would've dropped to O(n). If you also had carried the max-seen-so-far down the list, you would have dropped to O(n) time and O(1) space.
if i need to do the max code in iteration not recursive how the code will be ??
i first did an array
(do do-array (d l)
setf b (make-array (length d))
(do (((i=0)(temp d))
((> i (- l 1)) (return))
(setf (aref b i) (car temp))
(setq i (+ i 1))
(setq temp (cdr temp))))
I made this, hope it helps and it is recursive.
(defun compara ( n lista)
(if(endp lista)
n
(if(< n (first lista))
nil
(compara n (rest lista)))))
(defun max_lista(lista)
(if (endp lista)
nil
(if(compara (first lista) (rest lista))
(first lista)
(max_lista(rest lista)))))
A proper tail-recursive solution
(defun maximum (lst)
(if (null lst)
nil
(maximum-aux (car lst) (cdr lst))))
(defun maximum-aux (m lst)
(cond
((null lst) m)
((>= m (car lst)) (maximum-aux m (cdr lst)))
(t (maximum-aux (car lst) (cdr lst)))))
(defun maxx (l)
(if (null l)
0
(if(> (car l) (maxx(cdr l)))
(car l)
(maxx (cdr l)))))