scheme - remove odd atoms from a list - scheme

I feel like I'm close but I can't seem to get this right. Any ideas?
ex)
(removeOdd ‘(8 3 (3 7) 5)) => (8, ())
(removeOdd ‘(5 5 2)) => (2)
(define (removeOdd y)
(if (null? y) '()
(if (= (remainder (car y) 2) 0)
(cons (car y) (removeOdd (cdr y)))
(cons removeOdd (cdr y)))
))
This probably won't work for the case with a list being inside another list but I am more concerned about being able to return the list I make with 'cons'
edit - if i switch cons to list it doesn't exactly return the list either.

(define (remove-odd y)
(cond
((null? y) '())
((pair? (car y))
(cons (remove-odd (car y)) (remove-odd (cdr y))))
((= (remainder (car y) 2) 0)
(cons (car y) (remove-odd (cdr y))))
(else (remove-odd (cdr y)))))

(define (removeOdd y)
(if (null? y)
'()
(if (atom? (car y))
(if (= (remainder (car y) 2) 0)
(cons (car y) (removeOdd (cdr y)))
(removeOdd (cdr y))
)
(cons (removeOdd (car y)) (removeOdd (cdr y)))
))
I don't remember actually how to check whether something is atom, but this is what you need.

Related

Removing all ()'s from a sublist in Racket

I need to have the following program interaction:
(clean'(1 (2 () (3 () 4))()()(()) 5)) → (1 (2 (3 4)) 5)
This is what I have so far
define (emptyClear theList)
(cond ((null? theList) '())
((null? (car theList)) (emptyClear (cdr theList)))
(else (cons (car theList) (emptyClear (cdr theList))))))
(define (clean tree)
(cond ((null? tree) '())
((not (list? (car tree))) (cons (car tree) (prune (cdr tree))))
(cons (emptyClear (car tree)) (prune (cdr tree)))))
But this gives me: -> (1 5) as the output.
How can I solve this issue?
From the example the task seems to be not simply to remove empty lists from a tree, but to continue to perform this operation until possible (since '(())) is not an empty list, but it is removed nevertheless).
Here is a possible solution, tested with DrRacket.
(define (my-empty? x)
(cond ((null? x) #t)
((list? x) (andmap my-empty? x))
(else #f)))
(define (clean x)
(cond ((null? x) '())
((not (list? x)) x)
((my-empty? (car x)) (clean (cdr x)))
(else (cons (clean (car x)) (clean (cdr x))))))
(clean '(1 (2 () (3 () 4))()()((())) 5)) ;=> '(1 (2 (3 4)) 5)

Where is the error in this Scheme program?

I am getting "Error: Invalid lambda: (lambda (insert-all))."
(define permutations
(lambda (L)
(let
((insert-all
(lambda (e Ls)
(let
((insert-one
(lambda (L)
(letrec
((helper
(lambda(L R)
(if (null? R)
(list (append L(list e)R))
(helper (append L (list (car R) ) ) (cdr R) )
))))
(helper '() L)))))
(apply append(map insert-one Ls)))))))
(cond ((null? L) '() )
((null?(cdr L)) (list L))
(else (insert-all (car L) (permutations ((cdr L))))))))
It is supposed to return all permutations of a given list.
The form that you have provided in not valid scheme. Specifically, your highest-level let form does not have a body. You might be thinking that the cond clause is the body but owing to your parenthesis it is not part of the let. Honestly, this is the fault of your formatting. Here is a 'properly' formatted Scheme form:
(define (permutations L)
(let ((insert-all
(lambda (e Ls)
(let ((insert-one
(lambda (L)
(let helper ((L '()) (R L))
(if (null? R)
(list (append L (list e) R))
(helper (append L (list (car R)))
(cdr R)))))))
(apply append (map insert-one Ls))))))
(cond ((null? L) '())
((null? (cdr L)) (list L))
(else (insert-all (car L)
(permutations (cdr L)))))))
At least it compiles and runs, although it doesn't produce the right answer (although I don't know what the proper input it):
> (permutations '(a b c))
((c b a))
> (permutations '((a b) (1 2)))
(((1 2) (a b)))
Here is an implementation that works:
(define (permutations L)
(define (insert-all e Ls)
(apply append
(map (lambda (e)
(map (lambda (x) (cons e x)) Ls))
e)))
(cond ((null? L) '())
((null? (cdr L)) (map list (car L)))
(else (insert-all (car L)
(permutations (cdr L))))))
> (permutations '((a b) (1 2) (x y)))
((a 1 x) (a 1 y) (a 2 x) (a 2 y) (b 1 x) (b 1 y) (b 2 x) (b 2 y))
The basic structure of your code was fine; just the implementation of your insert-one and helper were lacking.

Encapsulating Certain Parts of List

I'm trying to write a procedure that "encapsulates" (i.e. puts in a list) elements of a list between a "separator" element.
(my-proc '(1 + 2))
=> ((1) (2))
(my-proc '(x * y + z ^ 2 + 1 + 5))
=> ((x * y) (z ^ 2) (1) (5))
(my-proc '((x + 1) * y + 5))
=> (((x + 1) * y) (5))
In this case the procedure can be hard-coded to define the + symbol as the separator.
Assume that foldr (fold right operation) is defined, I'd prefer that it'd be in terms of it.
I'm not giving a full solution since this looks really homework-y.
(define (split-expr expr)
(foldr (lambda (e es)
(if (eq? e '+)
<???> ; do split
(cons (cons e (car es))
(cdr es))))
<???> ; what should start be?
es))
Just for fun, here's a version in continuation-passing style (no foldr, probably not suitable as a homework answer):
(define split/cps
(λ (sep ls)
(let loop ([ls ls] [k (λ (item acc)
(if item (cons item acc) acc))])
(cond
[(null? ls)
(k #f '())]
[(eq? sep (car ls))
(loop (cdr ls)
(λ (item acc)
(k #f (if item (cons item acc) acc))))]
[else
(loop (cdr ls)
(λ (item acc)
(k (if item
(cons (car ls) item)
(list (car ls)))
acc)))]))))
Here's another way to do it, also without foldr:
(define split/values
(λ (sep ls)
(let loop ([ls ls])
(cond
[(null? ls)
'()]
[else
(let-values ([(a d) (car-to-sep sep ls)])
(if (null? a)
(loop d)
(cons a (loop d))))]))))
(define car-to-sep
(λ (sep ls)
(let loop ([ls ls] [a '()])
(cond
[(null? ls)
(values '() '())]
[(eq? sep (car ls))
(values '() (cdr ls))]
[else
(let-values ([(a d) (loop (cdr ls) a)])
(values (cons (car ls) a) d))]))))

What is wrong with my scheme code?

The function I wrote for SICP 2.20 is:
(define (same-parity x . y)
(if (null? (car y)
'()
(if (= (even? (car y)) (even? x))
(cons (car y) (same-parity (cons x (cdr y))))
(same-parity (cons x (cdr y))))))
And then I try to call it with
(same-parity 1 2 3 4 5 6 7)
The error I get is:
"The object #t, passed as the first argument to integer-equal? is not the correct type."
I thought that equal works with #t and #f...
An example of code I found online is the following, I ran it and it works. But, what am I doing wrong?
(define (same-parity a . rest)
(define (filter rest)
(cond ((null? rest) '())
((= (remainder a 2) (remainder (car rest) 2))
(cons (car rest) (filter (cdr rest))))
(else
(filter (cdr rest)))))
(filter (cons a rest)))
The = procedure accepts numbers. But even? returns a boolean not a number.
Use equal? instead of =.
equal? works with booleans.
For instance at the REPL:
> (even? 2)
#t
> (= (even? 2) (even? 2))
=: expects type <number> as 1st argument, given: #t; other arguments were: #t
> (equal? (even? 2) (even? 2))
#t

How to Assign Mulitpule Caulated Value Into List in Scheme

Okay this is my 4th question today on Scheme, still pretty new to Scheme, as I needed for one of my sub-function I asked earlier in the day.
Basically this will return me the difference of 2 lists. Say you've got (1,5) and (5,1) this function should return me 8. As that's the distance between l to w
Here is what I have. Note: if I change the (list (- (car l) (car w))) into (write ..... ) the function will work, but outputs 2 number which I have no idea how to use those number as inputs of my other function.
So I try to put it into list, but doesn't really work out, it returns me with no error but weird stuff
(define (difference l w) ; calc heuristic function estimation
(if (> (car l) (car w))
(list (- (car l) (car w)))
(if (< (car l) (car w))
(list (- (car w) (car l)))))
(if (< (list-ref l 1) (list-ref w 1))
(list (- (list-ref l 1) (list-ref w 1)))
(if (> (list-ref l 1) (list-ref w 1))
(list (- (list-ref w 1) (list-ref l 1)))))
)
Here is the code returned me
> (difference '(9 1) '(3 1))
#<procedure:...0\assigment 2.ss:50:3>
Any ideas? try to use lambda end-up the same thing.
Well first of all, there's a typo in your code...
(lits (- (car w) (car l)))))
should be...
(list (- (car w) (car l)))))
EDIT: Would something like this work?
(define (difference lst1 lst2)
(if (> (car lst1) (car lst2))
(+ (- (car lst1) (car lst2)) (difference (cdr lst1) (cdr lst2)))
(+ (- (car lst2) (car lst1)) (difference (cdr lst1) (cdr lst2))))
)
I know it's an old question, but I just wrote something like this. Here's my solution
(define (difference l1 l2)
(apply + (map abs (map - l1 l2))))

Resources