Scheme Inverting values - scheme

I'm trying to convert #t to #f, #f to #t and a negative number to a positive and the opposite.
(define inverse
(lambda (x)
(cond ((eq? x #t) #f)
((eq? x #f) #t)
(else - x))))
It works for the boolean but not the number.

(else - x) is not a valid form. Change it to (else (- x)).
Btw, you can go without cond:
(define (inverse x) (if (boolean? x) (not x) (- x)))

Related

scheme - remove odd atoms from a list

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.

Issues with conditionals in Scheme

I'm using Scheme with the full Swindle package, and I'm trying to use conditionals to recursively determine evenness/oddity of integers. My code is as follows:
(define (odd? x)(
(cond
((= x 0) '#f)
((= x 1) '#t)
((= (even? (- x 1)) #t) '#f)
(else '#t))))
(define (even? x)(
(cond
((= x 0) '#f)
((= x 2) '#t)
((= (odd? (- x 1)) #t) '#f)
(else '#t))))
However, when I run (even? x) or (odd? x) [x is some number, doesn't matter what, as I get the same error] I get: application: not a procedure;
expected a procedure that can be applied to arguments
given: #t
arguments...: [none]
Can anyone help? Thanks. I'm not 100% familiar with ideal Scheme syntax, so it might be that.
You have an erroneous pair of parentheses surrounding the cond expression (that's causing the error reported). But also, there are way too many conditions in each procedure, and because you're using = to compare numbers with boolean values, there will be a point where a contract violation will occur. For fixing that you can replace = with equal? in here:
((equal? (even? (- x 1)) #t) '#f)
And in here:
((equal? (odd? (- x 1)) #t) '#f)
But then, the procedures will still give an incorrect result:
(even? 5)
=> #t
(odd? 7)
=> #f
Honestly, I think it'd better to simplify the implementation, that will solve all the problems. Try this instead:
(define (odd? x)
(cond ((= x 0) #f)
(else (even? (- x 1)))))
(define (even? x)
(cond ((= x 0) #t)
(else (odd? (- x 1)))))
Now we'll get correct answers:
(even? 4)
=> #t
(even? 5)
=> #f
(odd? 6)
=> #f
(odd? 7)
=> #t
Any Scheme form in parentheses is an application, like (sin 42) or (42 sin). The first calls sin as a function with argument 42 and produces a value; the second tries to call 42 with an argument sin, but 42 is no procedure, so this causes an error. Similarly (42) is an application with no arguments; still it must have a procedure to be applied as its first part, to be called with no arguments, right? In Scheme, parentheses matter, they are not just for grouping stuff (as they may be in some other languages). So the extra parentheses cause an extra attempt to evaluate the result, which is a Boolean, i.e. not a procedure, so this is an error.
Then, '#f is just #f; similarly for #t (they both evaluate to themselves); and a condition (= test #t)1 (equal? test #t) is the same as just test (produces the same set of Boolean results) ((1 we can't use = to compare Booleans, it is supposed to be used with numbers only)):
(define (odd? x)
(cond
((= x 0) #f)
((= x 1) #t)
((even? (- x 1)) #f)
(else #t)))
Also, (if test #f else...) is the same as (if (not test) else... #f):
(define (odd? x)
(cond
((= x 0) #f)
((= x 1) #t)
((not (even? (- x 1))) #t)
(else #f))) ; (else ...) is like (#t ...)
using logical connectives, the clauses with the same outcome can be merged, and mutually exclusive clauses can be rearranged (mutual exclusivity can be achieved with explicit guards):
(define (odd? x)
(cond
((and (/= x 0) ; a guard
(or (= x 1)
(not (even? (- x 1))))) #t)
((or (= x 0) #t) #f)))
but (cond (test #t) (else #f) is (if test #t #f) which is just test:
(define (odd? x) (and (> x 0) ; `>` is better
(or (= x 1)
(not (even? (- x 1))))))
The guard (> x 0) prevents the fall-through for negative xes.
But then, this is completely wrong. For n to be odd, n-1 must be even, not the opposite!
(define (odd? x) (and (> x 0) ; work only for positive integers
(or (= x 1)
(even? (- x 1)))))
We could write (not (odd? (- x 1))), but then it wouldn't be tail recursive. It would be tail recursive modulo cons (not serving as a "constructor"), but for some historic fluke of a reason2, TRMC optimization isn't required of a Scheme implementation. The last expression in and and or forms is, in fact, in tail position. But not in not. ((2 despite being described as early as 1974.))
Repeat the same for your definition of even?.

Function that takes in X and return all sets for #t/#f

So ive been sitting here thinking of how to do this and im quite stuck,
i want it to work like
(Return_Set 2) returns=> ((#t, #t) (#t, #f) (#f, #t) (#f, #f))
(Return_Set 1) returns=> ((#t) (#f))
(define (Return_Set N)
I know for (/ (expt 2 N) 2) i need to put all #t then append it to:
(Return_Set N-1)
and do the same for #f but from there.
Here's an idea: write a procedure that returns the cartesian product between an arbitrary number of lists (hint: you'll find the algorithm by googling!). Then you'll be able to solve this problem easily, like this:
(return-set 1) ; is equivalent to (cartesian-product '(#t #f))
=> '((#t #f))
(return-set 2) ; is equivalent to (cartesian-product '(#t #f) '(#t #f))
=> '((#t #t) (#t #f) (#f #t) (#f #f))
(return-set 3) ; is equivalent to (cartesian-product '(#t #f) '(#t #f) '(#t #f))
=> '((#t #t #t) (#t #t #f) (#t #f #t) (#t #f #f)
(#f #t #t) (#f #t #f) (#f #f #t) (#f #f #f))
To make things easier, also write a procedure that builds a new list repeating a value n times. Now the solution to the problem can be easily expressed like this:
(define (cartesian-product . lsts)
<???>) ; ToDo
(define (repeat element n)
<???>) ; ToDo
(define (return-set n)
(apply cartesian-product
(repeat '(#t #f) n)))
I can give you a hand with the above procedures, but first let's see what have you tried so far, and I mean: a real effort with working code, in Stack Overflow it's frowned upon to spoon-feed answers to homeworks.
UPDATE:
Oh, well. #GoZoner gave a straight answer to OP's homework, so it doesn't make much sense to withhold my answer now. Here's a possible solution using Racket:
(define (cartesian-product . lsts)
(foldr (lambda (lst acc)
(for*/list ((x (in-list lst))
(y (in-list acc)))
(cons x y)))
'(())
lsts))
(define (repeat elt n)
(build-list n (const elt)))
(define (return-set n)
(apply cartesian-product
(repeat '(#t #f) n)))
This gets it done:
(define (return-set n)
(define (cons-of x)
(lambda (l) (cons x l)))
(assert (positive? n))
(if (= n 1)
'((#t) (#f))
(let ((n_1 (return-set (- n 1))))
(append (map (cons-of #f) n_1)
(map (cons-of #t) n_1)))))
The key insight it to recognize that the result for N is simply built on the result of N-1.

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