I can get the odd elements of a list using the following code:
(define (odds lis)
(cond
((null? lis) '())
((not (list? lis)) (quote (Usage: odds(list))))
((null? (car lis)) '())
((= (length lis) 1) (car lis))
(else (cons (car lis) (odds (cddr lis))))))
but when input list of odd length
For example: (odds '(a b c d e))
It will return
(a c . e)
How can i get rid of this obnoxious period?
Try this, it's a change in only one line:
(define (odds lis)
(cond
((null? lis) '())
((not (list? lis)) (quote (Usage: odds(list))))
((null? (car lis)) '())
((= (length lis) 1) lis) ; change here
(else (cons (car lis) (odds (cddr lis))))))
In the highlighted line, you were returning a single element instead of a proper list (a null-terminated list), that's what was causing the problem.
Related
I am stuck with this particular problem I was doing for fun:
Why does it cause a contract violation everytime car comes around? And are there any possible fixes?
(define (fv expr)
(cond ((eq? (car expr) 'lambda) (fv (cadr (cdr expr))))
((pair? (car expr)) (union (fv (car expr)) (fv (cdr expr))))
((symbol? (car expr)) (remove (car expr) (fv (cdr expr))))
(else '())))
(define (union set1 set2)
(cond ((null? set1) set2)
((member (car set1) set2) (union (cdr set1) set2))
(else (cons (car set1) (union (cdr set1) set2)))))
(define (remove item set)
(cond ((null? set) '())
((equal? item (car set)) (cdr set))
(else (cons (car set) (remove item (cdr set))))))
Input = (fv '(λ f (λ x (f ((t g) g)))))
Output =
car: contract violation expected: pair? given: '()
Output Should Be: (t g)
The error message:
car: contract violation expected: pair? given: '()
means that the function car was called with the argument '() (the empty list) and this gives an error.
Now you know that the problem is related to a call to car.
Since car is called multiple times in your program it is hard
to spot which car is the culprit. Presumably your Scheme implementation
displays a source locations that points to the offending expression.
But let's say you are not so lucky. In that case, you'll need to figure out which function has the problem. Inserting a few calls to display helps:
(define (fv expr)
(display (list 'fv: 'expr expr) (newline)
(cond ((eq? (car expr) 'lambda) (fv (cadr (cdr expr))))
((pair? (car expr)) (union (fv (car expr)) (fv (cdr expr))))
((symbol? (car expr)) (remove (car expr) (fv (cdr expr))))
(else '())))
(define (union set1 set2)
(display (list 'union: 'set1 set1 'set2 set2) (newline)
(cond ((null? set1) set2)
((member (car set1) set2) (union (cdr set1) set2))
(else (cons (car set1) (union (cdr set1) set2)))))
(define (remove item set)
(display (list 'remove: 'item item 'set set) (newline)
(cond ((null? set) '())
((equal? item (car set)) (cdr set))
(else (cons (car set) (remove item (cdr set))))))
If you try your example now, you'll see which function is called before the error occurs. In this case, I bet the problem is fv. Here car is called without a check that the argument is a non-empty list first.
I am trying to get all the even and positive elements in scheme
I have the following code
(define (getVals lis)
(cond
((null? lis) lis)
(((> (car lis) 0) (even? (car lis)))
(cons (getVals (cdr lis))))
)
)
To check my code im using
getVals '(2 -2 4 6 5))
Which should output a new list with positive and even numbers (2 4 6)
Thank you
The simplest way would be to use built-in procedures:
(define (getVals lis)
(filter (lambda (x) (and (even? x) (positive? x)))
lis))
If you want to implement it from scratch, you need to fix your code:
It's missing the case where the current element does not meet the conditions (the else case).
It's missing one parameter when calling cons.
The condition is missing an and.
This is what I mean:
(define (getVals lis)
(cond
((null? lis) lis)
((and (even? (car lis)) (positive? (car lis)))
(cons (car lis) (getVals (cdr lis))))
(else (getVals (cdr lis)))))
Either way, it works as expected:
(getVals '(2 -2 4 6 5))
=> '(2 4 6)
And just to add to #OscarLopez's answer - if you have a second look you will see, that getVals is just the specific case of `filter.
(define (getVals lis)
(cond
((null? lis) lis)
((and (even? (car lis)) (positive? (car lis)))
(cons (car lis) (getVals (cdr lis))))
(else (getVals (cdr lis)))))
Versus:
(define (filter func lst)
(cond
((null? lis) lst)
((func (car lst))
(cons (car lst) (filter func (cdr lst))))
(else (filter func (cdr lst)))))
With filter func as getVales, and
with func as:
(lambda (x) (and (even? x) (positive? x)))
getVals is just a special case of filter:
(define (getVals lst)
(filter (lambda (x) (and (even? x) (positive? x))) lst))
But you should follow the style guide for Lisp languages -
don't use camelCase for function names but prefer the lisp-typic form get-vals.
This is what i have so far, kindly assist on where im going wrong
(define helper
(lambda (lis)
(cond
((null? lis) 0)
((null? (cdr lis)) 0)
(else (+ (helper (cdr (cdr lis))))))))
(define (sumEven lis)
(display (helper lis)))
This is how i call the function:
(define (sumEven lis)
(display (helper lis)))
You forgot to add the element:
(else (+ (car (cdr lis)) (helper (cdr (cdr lis))))))))
I need to remove consecutive duplicates from a list in Scheme for ex:
(remove '(e f f g h h e e))
should return
(e f g h e)
This is what I have but I keep getting an error:
(define (remove lst)
(cond
((null? lst '())
((null? (cdr lst)) '())
((equal? (car lst)(car(cdr lst)))(remove(cdr lst)))
(cons(car lst)(remove (cdr lst))))))
I thought I was on the right track but I can't see what I'm doing wrong.
The parentheses are incorrect in the first case, and in the last case you forgot to write the else. Also, the second case is incorrect; this is what I mean:
(define (remove lst)
(cond
((null? lst) '())
((null? (cdr lst)) lst)
((equal? (car lst) (car (cdr lst))) (remove (cdr lst)))
(else (cons (car lst) (remove (cdr lst))))))
I have been working on the following function flatten and so far have it working for just lists. I was wondering if someone could provide me with some insight on how to get it work with pairs? For example (flatten '(a .a)) would return (a a). Thanks.
(define (flatten list)
(cond ((null? list) null)
((list? (car list)) (append (flatten (car list)) (flatten (cdr list))))
(else
(cons (car list) (flatten (cdr list))))))
Here's one option:
(define (flatten x)
(cond ((null? x) '())
((pair? x) (append (flatten (car x)) (flatten (cdr x))))
(else (list x))))
This does what you want, without requiring append, making it o(n). I walks the list as a tree. Some schemes might throw a stack overflow error if the list is too deeply nested. In guile this is not the case.
I claim no copyright for this code.
(define (flatten lst)
(let loop ((lst lst) (acc '()))
(cond
((null? lst) acc)
((pair? lst) (loop (car lst) (loop (cdr lst) acc)))
(else (cons lst acc)))))
(define (flatten l)
(cond
[(empty? l) empty]
[(list? l)
(append (flatten (first l))
(flatten (rest l)))]
[else (list l)]))