Omitting parentheses in cond leads to strange result - scheme

Consider the following snippet
(define (f a b c)
(
cond ((and (< b c) (< b a)) (+ c a))
((and (< a c) (< a b)) (+ c b))
((and (< c b) (< c a)) (+ b a))
)
)
(display (f 2 1 3)) ; 5
(newline)
(display (f 2 8 3)) ; 11
(newline)
(display (f 2 8 -3)) ; 10
Now if I comment the second line and second line from bottom
(define (f a b c)
;(
cond ((and (< b c) (< b a)) (+ c a))
((and (< a c) (< a b)) (+ c b))
((and (< c b) (< c a)) (+ b a))
;)
)
The result is
#<undef>
11
10
I could not explain why omitting the parentheses lead to that result. In the second case, I expected thtat the complier would treat cond ((and (< b c) (< b a)) (+ c a)), ((and (< a c) (< a b)) (+ c b)) and ((and (< a c) (< a b)) (+ c b)) as three expressions, the latter two invalid, instead it seems they got executed.

Normally cond keyword should raise an exception when it's interpreted.
But, if your interpreter does not throw any error, you are in the case of block statement, in which the evaluation of the last expression provides the result, the other ones are computed only for side-effects. The code reduces to this:
(define (f a b c) ((and (< c b) (< c a)) (+ b a))))

Related

How to compute the number of times pattern in one list appears in other list in Scheme

I am stuck up in a Scheme program for about 5 hours. The program that I am working on should take two lists as input and then compute the number of times the pattern within the first list appears on the second list.
For example : > (patt '(b c) '(a b c d e b c)) ==> answer = 2
(patt '(a b c) '(a b c a b c d e a b c c c)) ==> answer = 3
(patt '((a b) c) '(a b (a b) c d e b c)) ==> answer = 1
Below is the code that I have till now.
(define (patt lis1 lis2)
(cond
((null? lis1) 0)
((null? lis2) 0)
[(and (> (length lis1) 1) (eq? (car lis1) (car lis2))) (patt (cdr lis1) (cdr lis2))]
((eq? (car lis1) (car lis2)) (+ 1 (patt lis1 (cdr lis2))))
(else (patt lis1 (cdr lis2)))
))
Can someone please help me solve this. Thanks!
Consider the subproblem of testing if a list starts with another list.
Then do this for every suffix of the list. Sum up the count of matches.
If you want non overlapping occurrences, you can have the prefix match, return the suffix of the list so that you can skip over the matching part.
Also use equals? for structural equality, not eq? which is for identity.
You need to divide the problem into parts:
(define (prefix? needle haystack)
...)
(prefix? '() '(a b c)) ; ==> #t
(prefix? '(a) '(a b c)) ; ==> #t
(prefix? '(a b c) '(a b c)) ; ==> #t
(prefix? '(a b c d) '(a b c)) ; ==> #f
(prefix? '(b) '(a b c)) ; ==> #t
(define (count-occurences needle haystack)
...)
So with this you can imagine searching for the pattern (count-occurences '(a a) '(a a a a)). When it is found from the first element you need to search again on the next. Thus so that the result is 3 for the (a a a a) since the matches overlap. Every sublist except when it's the empty list involves using prefix?
Good luck!
(define (patt list1 list2)
(let ([patt_length (length list1)])
(let loop ([loop_list list2]
[sum 0])
(if (>= (length loop_list) patt_length)
(if (equal? list1 (take loop_list patt_length))
(loop (cdr loop_list) (add1 sum))
(loop (cdr loop_list) sum))
sum))))
After giving this homework problem a little time to marinate, I don't see the harm in posting additional answers -
(define (count pat xs)
(cond ((empty? xs)
0)
((match pat xs)
(+ 1 (count pat (cdr xs))))
(else
(count pat (cdr xs)))))
(define (match pat xs)
(cond ((empty? pat)
#t)
((empty? xs)
#f)
((and (list? pat)
(list? xs))
(and (match (car pat) (car xs))
(match (cdr pat) (cdr xs))))
(else
(eq? pat xs))))
(count '(a b c) '(a b c a b c d e a b c c c)) ;; 3
(count '((a b) c) '(a b (a b) c d e b c)) ;; 1
(count '(a a) '(a a a a)) ;; 3

DrRacket/Scheme: not a procedure

I am trying to create program in Scheme (DrRacket) to solve roots of quadratic equation. I have also function to solve discriminant (function D). If discriminant is >0 function root should have on the output "point pair" (is that the correct word? english is not my native language) of both roots. Else it should give #f on the output.
(define na2
(lambda (x)
(* x x)))
(define D
(lambda (a b c)
(- (na2 b) (* 4 a c))))
(define roots
(lambda (a b c)
((if (> (D a b c) 0)
(cons (/ (+ (- b) (sqrt (D a b c))) (* 2 a)) (/ (- (- b) (sqrt (D a b c))) (* 2 a)))
#f)))
It gives me this:
> (roots 1 3 2)
>: contract violation
expected: real?
given: (-1 . -2)
argument position: 1st
other arguments...:
>
As you can see the correct output is there, but why the error?
Edit:
I corrected typo, as Parakram Majumdar helepd me, now it gives me
application: not a procedure;
expected a procedure that can be applied to arguments
given: (-1 . -2)
arguments...: [none]
Can someone please tell what am I doing wrong?
As discussed in the comments, the if statement should be written as follows:
(if cond then else)
where the condition would be :
(> (D a b c) 0)
So overall it should be:
(define roots
(lambda (a b c)
(if (> (D a b c) 0)
(cons (/ (+ (- b) (sqrt (D a b c))) (* 2 a))
(/ (- (- b) (sqrt (D a b c))) (* 2 a)))
#f
)))

How to make this function elegant

In response to the following exercise from the SICP,
Exercise 1.3. Define a procedure that takes three numbers as arguments
and returns the sum of the squares of the two larger numbers.
I wrote the following (correct) function:
(define (square-sum-larger a b c)
(cond ((or (and (> a b) (> b c)) (and (> b a) (> a c))) (+ (* a a) (* b b)))
((or (and (> a c) (> c b)) (and (> c a) (> a b))) (+ (* a a) (* c c)))
((or (and (> b c) (> c a)) (and (> c b) (> b a))) (+ (* b b) (* c c)))))
Unfortunately, that is one of the ugliest functions I've written in my life. How do I
(a) Make it elegant, and
(b) Make it work for an arbitrary number of inputs?
I found an elegant solution (though it only works for 3 inputs):
(define (square-sum-larger a b c)
(+
(square (max a b))
(square (max (min a b) c))))
If you're willing to use your library's sort function, this becomes easy and elegant.
(define (square-sum-larger . nums)
(define sorted (sort nums >))
(let ((a (car sorted))
(b (cadr sorted)))
(+ (* a a) (* b b))))
In the above function, nums is a "rest" argument, containing a list of all arguments passed to the function. We just sort that list in descending order using >, then square the first two elements of the result.
I don't know if it's elegant enough but for a 3 argument version you can use procedure abstraction to reduce repetition:
(define (square-sum-larger a b c)
(define (square x)
(* x x))
(define (max x y)
(if (< x y) y x))
(if (< a b)
(+ (square b) (square (max a c)))
(+ (square a) (square (max b c)))))
Make it work for an arbitrary number of inputs.
(define (square-sum-larger a b . rest)
(let loop ((a (if (> a b) a b)) ;; a becomes largest of a and b
(b (if (> a b) b a)) ;; b becomes smallest of a and b
(rest rest))
(cond ((null? rest) (+ (* a a) (* b b)))
((> (car rest) a) (loop (car rest) a (cdr rest)))
((> (car rest) b) (loop a (car rest) (cdr rest)))
(else (loop a b (cdr rest))))))
A R6RS-version using sort and take:
#!r6rs
(import (rnrs)
(only (srfi :1) take))
(define (square-sum-larger . rest)
(apply +
(map (lambda (x) (* x x))
(take (list-sort > rest) 2))))
You don't need to bother sorting you just need the find the greatest two.
(define (max-fold L)
(if (null? L)
#f
(reduce (lambda (x y)
(if (> x y) x y))
(car L)
L)))
(define (remove-num-once x L)
(cond ((null? L) #f)
((= x (car L)) (cdr L))
(else (cons (car L) (remove-once x (cdr L))))))
(define (square-sum-larger . nums)
(let ((max (max-fold nums)))
(+ (square max)
(square (max-fold (remove-num-once max nums))))))
(square-sum-larger 1 8 7 4 5 6 9 2)
;Value: 145

what is wrong this scheme code?

I'm studying sicp.
this question is ex 1.3.
I can't understand why this code is problem.
please help me.. TT
here's the code.
(define (test a b c)
(cond ((and (< a b) (< a c)) (+ (* b b) (* c c))
(and (< b a) (< b c)) (+ (* a a) (* c c))
(else (+ (* b b) (* c c)))
))
(test 1 2 3)
error is
Premature EOF on #[input-port 60 from buffer at #[mark 61 #[buffer 17]
166 left]
Your syntax for cond is wrong. Here is the same code with the correct syntax:
(define (test a b c)
(cond ((and (< a b) (< a c)) (+ (* b b) (* c c)))
((and (< b a) (< b c)) (+ (* a a) (* c c)))
(else (+ (* b b) (* c c)))))
However, your code is still wrong. Can you see why? (Hint: what does the else branch signify, and what expression should be there?)
Missing parentheses.
(define
(test a b c)
(cond
((and (< a b) (< a c)) (+ (* b b) (* c c)))
((and (< b a) (< b c)) (+ (* a a) (* c c)))
(else (+ (* b b) (* c c))))

Scheme Cons (with #f as a second statement) output

I was wondering, If
(cons (quote (a b c)) #f)
gives an output
(( a b c ))
Then what output does this give:
(cons (quote (a b c)) #t)
?
Thank you
The first expression will not evaluate to ((a b c)) in most interpreters, it seems that your interpreter is evaluating #f as an empty list:
(cons (quote (a b c)) '())
=> '((a b c))
Having said that, you just substituted a #f with a #t, the standard results will look like this:
(cons (quote (a b c)) #f)
=> '((a b c) . #f)
(cons (quote (a b c)) #t)
=> '((a b c) . #t)
Why don't you try it online? in here for instance.
CommonLisp:
* (if '() 'true 'false)
FALSE
Scheme:
> (if '() 'true 'false)
true
And back in CommonLisp:
* (cons (quote (a b c)) nil)
((A B C))

Resources