I am trying to run this code that supposedly removes duplicates from a sorted list of numbers.
(defun unique (x)
(cond( (null x) x )
( (null (cdr x)) x )( (equal (car x) (cdr x)) (unique (cdr x)) )( t (cons (car x) (unique (cdr x))) )))
I am trying to call this function by typing:
(print (unique '(2 2 3 4 4 5)))
My output is currently shown as follows:
(2 2 3 4 4 5)
Clearly, this doesn't seem to be removing the duplicates, if anything at all.
There is an error in the form: (equal (car x) (cdr x)). car returns the first element of a list, while cdr returns the rest of the list, so the comparison is not between the first and the second element of the list, but between the first element and the list without the first element (and this comparison will always produces false for regular lists).
To correct the error, the function should use cadr instead of cdr: (equal (car x) (cadr x)): the function cadr (or its synonym second) is equivalent to car (cdr and returns the second element of a list. So this is the correct version:
CL-USER> (defun unique (x)
(cond ( (null x) x )
( (null (cdr x)) x )
( (equal (car x) (cadr x)) (unique (cdr x)) )
( t (cons (car x) (unique (cdr x))) )))
UNIQUE
CL-USER> (unique '(1 1 2 2 3))
(1 2 3)
Related
I'm not been able to make this working on. I'm defining a predicate using deftype SameType(x y) method, which evaluates whether the elements of list x and list y are of the same type, and in the same position. The problem comes when I try to call the predicate for testing. I receive an error ERROR: SameType is undefined This is my code:
(deftype SameType (x y)
`(cond
((and (null x) (null y) T))
(
(and (numberp (car x)) (numberp (car y)))
(SameType (cdr x) (cdr y) )
)
(
(and (stringp (car x)) (stringp (car y)))
(SameType (cdr x) (cdr y) )
)
(
(and (atom (car x)) (atom (car y)))
(SameType (cdr x) (cdr y) )
)
(T nil)
)
)
And this is how I'm calling it
(SameType '(A B C 1 2 4 A) '('() G 2 5 6 A B))
I already checked on various onine resources, even related questions on this site.
deftype can be used to define a type, not a predicate. For instance, to define the type of the lists with only integers, you could write something like:
(defun intlistp (l)
"predicate to check if l is a list consisting only of integers"
(and (listp l) ; l is a list and
(every #'integerp l))) ; every element of l is an integer
(deftype integer-list ()
"the type of list of integers"
`(satisfies intlistp))
and then you can check if a value satisfies this type:
CL-USER> (typep '(1 2 3) 'integer-list)
T
CL-USER> (typep '(1 2.5 3) 'integer-list)
NIL
If you want to check if two lists have the same type according to your definition, then you could define a regular function:
(defun same-type (l1 l2)
"check if lists l1 and l2 have the same length and corresponding
elements of the same CL type"
(cond ((null l1) ; if l1 is null
(null l2)) ; returns true only if also l2 is null
((and (consp l1) ; if l1 is a cons
(consp l2) ; and l2 is a cons too,
(typep (car l1) (type-of (car l2)))) ; and their cars have the same CL type
(same-type (cdr l1) (cdr l2))))) ; go recursively on their cdrs
CL-USER> (same-type '(1 a 3) '(2 b 4))
T
CL-USER> (same-type '(1 "a" 3) '(2 "b" 3))
T
CL-USER> (same-type '(1 a 3) '(2 b 4.5))
NIL
CL-USER> (same-type '(1 a 3) '(2 b 4 3))
NIL
CL-USER> (same-type '(1 2 (3 4)) '(1 6 (4 5)))
T
CL-USER> (same-type '(1 2 (3 4)) '(1 6 (4 5 6)))
T
Note that, as you can see from the last example, the type is checked only for the first level of the list.
Specifically, I have the following function
(define (even-odd-filter x . intlist)
(if (equal? '() intlist)
'()
(if (equal? (modulo x 2) (modulo (car intlist) 2))
(cons (car intlist) (even-odd-filter x (cdr intlist)))
(even-odd-filter x (cdr intlist)))))
Can someone please explain why this would break on the second iteration?
As far as I know, (car list) is meant to refer to the first element of list, however, in the second recursive call
(modulo (car int list) 2)
causes an error as the interpreter believes that (car intlist) references the whole list as opposed to the first element of said list.
I am quite lost on this, and any help would be appreciated.
The reason why is that if you call (even-odd-filter 5 1 2 3) it will do
(cons 1 (even-odd-filter 5 '(2 3))) and intlist will be ((2 3)) in the second iteration.
To avoid this it's best to use a helper such that only the outer call has rest arguments:
(define (even-odd-filter x . intlist)
(let helper ((intlist intlist))
(cond
((null? intlist) '())
((equal? (modulo x 2) (modulo (car intlist) 2))
(cons (car intlist) (helper (cdr intlist))))
(else
(helper (cdr intlist))))))
Another nice thing with this is that x, that doesn't change in he iteration isn't passed but used as a free variable. It makes easier to read code. Since you have nested if I turned it into cond which is for a typical if-then-else scenario.
If you really want rest arguments in recursion, you need to use apply in each recursive call. This is not very efficient since it most likely will create a new list each iteration:
(define (even-odd-filter x . intlist)
(if (equal? '() intlist)
'()
(if (equal? (modulo x 2) (modulo (car intlist) 2))
(cons (car intlist) (apply even-odd-filter x (cdr intlist)))
(apply even-odd-filter x (cdr intlist)))))
The reason is that if you define a function with the syntax:
(define (function arg1 . rest-of-args-as-list) body)
you should call it always with a certain number of arguments, but not with a list. For instance, assuming you need to operate on a sequence of integers, you can call it in this way:
(function 1 2 3 4 5)
and inside the body of the function arg1 will be bound to 1 and rest-of-args-as-list will be bound to the list (2 3 4 5).
So in you case, if you call the function: (even-odd-filter 1 2 3 4 5), x will be bound to 1, intlist to (2 3 4 5) and in the second iteration, the function will be called as: (even-odd-filter 1 (3 4 5)) (since x is 1 and cdr of (2 3 4 5) is (3 4 5)).
And calling it in this way will produce the error (in DrRacket):
modulo: contract violation
expected: integer?
given: '(3 4 5)
argument position: 1st
other arguments...:
>
How could you solve this problem?
A possibility is to define the function with a single argument which is a list. Here is a rewriting of your function in this way:
(define (even-odd-filter intlist)
(cond ((equal? '() intlist) '())
((equal? '() (cdr intlist)) intlist)
((equal? (modulo (car intlist) 2) (modulo (cadr intlist) 2))
(cons (cadr intlist) (even-odd-filter (cons (car intlist) (cddr intlist)))))
(else (even-odd-filter (cons (car intlist) (cddr intlist))))))
i am trying to write a function in Scheme that takes in a list and an integer and outputs the same list minus all the members less than the integer... please help. I seem to be unable to add the numbers into a new list that can be outputed.
(define result '())
(display result)
(define nums-less-than-x
(lambda (lst x)
(define impl
(lambda (l1 b result)
(if (null? l1) result
(begin (if (> b (car l1))
(begin (cons (car l1) result)
;(display result)(newline)(newline)
(display (car l1) )(newline))
)
(impl (cdr l1) b result)
))
))
(impl lst x result)
))
(display (show-up '(4 6 3 -8 3 4) 5))
The code juss displays (), an empty list like that, when I run
(display (num-less-than-x '(some list) x))
Your result is never updated. usually I would expect that only when the element is not being a part of the result and otherwise a recursion like:
(impl (cdr l1) b (cons (car l1) result))
I notice that you have put debug output as the last expression in a begin, eg.
(begin
expression-that-does-something
(display ...)
(newline))
Note that the expressions result is not the result, but the result from the newline, typically some undefined value. You need to put your debug stuff first then as the tail the expression your function should return. Alternatively you could make a debug function:
(define (debug expr)
(display expr)
(newline)
expr))
My understanding is that you want the procedure to return the result, not to display it, which is the right way to do it:
(define show-up
(lambda (lst mx)
(if (null? lst)
lst
(let ((c (car lst)))
(if (> c mx)
(show-up (cdr lst) mx)
(cons c (show-up (cdr lst) mx)))))))
Testing:
> (show-up '(4 6 3 -8 3 4) 5)
'(4 3 -8 3 4)
When programming in a functional style, we try to use existing procedures to solve a problem. With that in mind, the preferred solution would be:
(define (show-up-to-n lst x)
(filter (lambda (n) (< n x))
lst))
Also notice that in truly functional code we avoid at all costs procedures that modify state (such as set!), it's a better idea to create a new list with the result.
The problem is to:
Write a function (encode L) that takes a list of atoms L and run-length encodes the list such that the output is a list of pairs of the form (value length) where the first element is a value and the second is the number of times that value occurs in the list being encoded.
For example:
(encode '(1 1 2 4 4 8 8 8)) ---> '((1 2) (2 1) (4 2) (8 3))
This is the code I have so far:
(define (encode lst)
(cond
((null? lst) '())
(else ((append (list (car lst) (count lst 1))
(encode (cdr lst)))))))
(define (count lst n)
(cond
((null? lst) n)
((equal? (car lst) (car (cdr lst)))
(count (cdr lst) (+ n 1)))
(else (n)))))
So I know this won't work because I can't really think of a way to count the number of a specific atom in a list effectively as I would iterate down the list. Also, Saving the previous (value length) pair before moving on to counting the next unique atom in the list. Basically, my main problem is coming up with a way to keep a count of the amount of atoms I see in the list to create my (value length) pairs.
You need a helper function that has the count as additional argument. You check the first two elements against each other and recurse by increasing the count on the rest if it's a match or by consing a match and resetting count to 1 in the recursive call.
Here is a sketch where you need to implement the <??> parts:
(define (encode lst)
(define (helper lst count)
(cond ((null? lst) <??>)
((null? (cdr lst)) <??>))
((equal? (car lst) (cadr lst)) <??>)
(else (helper <??> <??>))))
(helper lst 1))
;; tests
(encode '()) ; ==> ()
(encode '(1)) ; ==> ((1 1))
(encode '(1 1)) ; ==> ((1 2))
(encode '(1 2 2 3 3 3 3)) ; ==> ((1 1) (2 2) (3 4))
Using a named let expression
This technique of using a recursive helper procedure with state variables is so common in Scheme that there's a special let form which allows you to express the pattern a bit nicer
(define (encode lst)
(let helper ((lst lst) (count 1))
(cond ((null? lst) <??>)
((null? (cdr lst)) <??>))
((equal? (car lst) (cadr lst)) <??>)
(else (helper <??> <??>)))))
Comments on the code in your question: It has excess parentheses..
((append ....)) means call (append ....) then call that result as if it is a function. Since append makes lists that will fail miserably like ERROR: application: expected a function, got a list.
(n) means call n as a function.. Remember + is just a variable, like n. No difference between function and other values in Scheme and when you put an expression like (if (< v 3) + -) it needs to evaluate to a function if you wrap it with parentheses to call it ((if (< v 3) + -) 5 3); ==> 8 or 2
This question already has answers here:
Flattening a tree structure in Lisp
(3 answers)
Closed 8 years ago.
I am new to lisp and I am trying to code a function that will turn a list with sub-lists such as (1 2 (3 (4)) 5) in to a list like this (1 2 3 4 5). The thing is, I have no idea how to put 2 orders in one condition. For example here is my code
(defun Func1 (x y)
(cond
((null x) y)
((listp (CAR x)) (Func1 (CDR x) (append y (CAR x) )) )
(T (Func1 (CDR x) (CONS (CAR x) y) ) ) ) )
Well, I know that I need to change the second condition, so if the first element of x is a list, then i will call the same function like (Func1 (CAR x) y) but if I do that i will only get the items of the sub-list and I am going to lose the other part of the list. So basiclly, my question is, how do I tell LISP that after it finishes with this line
((listp (CAR x)) (Func1 (CDR x) (append y (CAR x) )) )
it should continue executing the other line
(T (Func1 (CDR x) (CONS (CAR x) y) ) ) ) )
I don't understand why your function takes 2 arguments when it's going to rearrange one list.
Your t case is almost correct, but you've practically turned it inside out - it should be
(cons (car x) (Func1 (cdr x)))
That is, a list where the car is the same as in the input, and the cdr is the result of flattening the cdr of the input.
The listp case looks like it's suffering from a similar form of "inside-out-ness".
Apart from the inexplicable y you have all the right bits but in the wrong order, except that it needs two Func1 calls - one for the car and one for the cdr.
I'll leave the rearrangement of the bits in that case as an exercise.