How do I use a pair to find which of two functions will evaluate the largest value? Scheme - scheme

Basically there is a pair made up of two functions and the code has to take the pair input x to find the highest evaluation for x and print that evaluation.
I receive the error:
car: contract violation expected: pair? given: 4
define (max x)
(lambda (x) ;I wanted lambda to be the highest suitable function
(if (> (car x) (cdr x))
(car x)
(cdr x))))
(define one-function (lambda (x) (+ x 1)))
(define second-function (lambda (x) (+ (* 2 x) 1))) ;my two functions
((max (cons one-function second-function)) 4)

And where are the functions being called? And you have two parameters called x, they must have different names. Try this:
(define (max f) ; you must use a different parameter name
(lambda (x)
(if (> ((car f) x) ((cdr f) x)) ; actually call the functions
((car f) x)
((cdr f) x))))
Now it'll work as expected:
((max (cons one-function second-function)) 4)
=> 9

Related

Scheme program to get average not recognizing last number

I've created this super simple program to take a list from the console and return the average. For whatever reason I always get an error message saying the last number of the list is not a number. Here's my code:
(define getline (lambda ()
(read-line (current-input-port))
)
)
(define getlist (lambda ()
(let ((input (getline)))
(if (not (equal? input "end"))
(cons input (getlist))
' ()
)
)
)
)
(define x (getlist))
(define (sum x)
(if (null? x)
0
(+ (car x) (sum (cdr x)))))
(define (average x)
(/ (sum x) (length x)))
(display (average x) (current-output-port))
You don't mention what scheme implementation you're using, but read-line functions usually return a string. You have to convert those strings to numbers first to be able to add them:
(define x (map string->number (getlist)))
or else
(define (sum x)
(if (null? x)
0
(+ (string->number (car x)) (sum (cdr x)))))
or something else along those lines.

Scheme - Return a list of pairs from 2 given lists

I'm working on this procedure which is supposed to return a list of pairs from 2 given lists. So for example (pairs '(1 2 3) '(a b c)) should return '((1.a) (2.b) (3.c)).
This is my logic so far. I would take the first element of each list and recursively call the procedure again with cdr as the new arguments. My result is returning a list such as this: (1 a 2 b 3 c)
Where is my logic going wrong? I know there is a list missing somewhere, but I'm not an expert at Scheme.
Any suggestions?
(define pairs
(lambda (x y)
(if (or (null? x) (null? y))
'()
(cons (car x)
(cons (car y)
(pairs (cdr x)(cdr y)))))))
(pairs '(1 2 3) '(a b c))
Notice that you produce a value that prints as (1 . 3) by evaluating (cons 1 3). However in your program you are doing (cons 1 (cons 3 ...)) which will prepend 1 and 3 to the following list.
In other words: Instead of (cons (car x) (cons (car y) (pairs ...))
use (cons (cons (car x) (car y) (pairs ...)).
Using map simplifies it a lot:
(define (pairs x y)
(map (λ (i j) (list i j)) x y))
Testing:
(pairs '(1 2 3) '(a b c))
Output:
'((1 a) (2 b) (3 c))
The result you're looking for should look like this:
((1 a) (2 b) (3 c))
In reality this structure is similar to this:
(cons
(cons 1 a)
(cons
(cons 2 b)
(cons
(cons 3 c)
'()
)
)
)
So what you're looking for is to append pairs to a list instead of adding all items to the list like you do. Simply your result looks like this:
(1 (2 (pairs ...)))
Your code should look like this:
(define pairs
(lambda (x y)
(if (or (null? x) (null? y))
'()
(cons
(cons (car x) (car y))
(pairs (cdr x) (cdr y))))))
This code might work, but it isn't perfect. We could make the code pass the list we create as a third parameter to make the function tail recursive.
You'd have something like this:
(define pairs
(lambda (x y)
(let next ((x x) (y y) (lst '()))
(if (or (null? x) (null? y))
(reverse lst)
(next (cdr x)
(cdr y)
(cons
(cons (car x) (car y))
lst))))))
As you can see, here since we're adding next element at the beginning of the list, we have to reverse the lst at the end. The difference here is that every time next is called, there is no need to keep each state of x and y in memory. When the named let will return, it won't be necessary to pop all the values back to where it called. It will simply return the reversed list.
That said, instead of using reverse we could simply return lst and use (append lst (cons (car x) (car y))) which would append the pair at the end of the list... Since lists are linked lists... in order to append something at the end of the list, scheme has to walk over all list items... which migth not be good with big list. So the solution is to add everything and at the end reorder the list as you wish. The reverse operation would happen only once.

Convert lists into functions

I have a little noob question. I have to do a homework on genetic programming in scheme and the first step is to finish some given functions.
I got to a point where i have to execute a randomly generated function with all the possible parameters in a range (using map). The "function" is list like '(* (+ 1 x) (- x (* 2 3))).
How can i execute it with a given parameter? (for example x = 2). By the way, the generated function has a maximum of 1 parameter (it's x or none).
Thanks!
Here's my solution:
(define (execute expr)
(lambda (x)
(let recur ((expr expr))
(case expr
((x) x)
((+) +)
((-) -)
((*) *)
((/) /)
(else
(if (list? expr)
(apply (recur (car expr)) (map recur (cdr expr)))
expr))))))
Example usage:
> (define foo (execute '(* (+ 1 x) (- x (* 2 3)))))
> (foo 42)
=> 1548

How to do square in RACKET

Here is my code:
(define (squares 1st)
(let loop([1st 1st] [acc 0])
(if (null? 1st)
acc
(loop (rest 1st) (* (first 1st) (first 1st) acc)))))
My test is:
(test (sum-squares '(1 2 3)) => 14 )
and it's failed.
The function input is a list of number [1 2 3] for example, and I need to square each number and sum them all together, output - number.
The test will return #t, if the correct answer was typed in.
This is rather similar to your previous question, but with a twist: here we add, instead of multiplying. And each element gets squared before adding it:
(define (sum-squares lst)
(if (empty? lst)
0
(+ (* (first lst) (first lst))
(sum-squares (rest lst)))))
As before, the procedure can also be written using tail recursion:
(define (sum-squares lst)
(let loop ([lst lst] [acc 0])
(if (empty? lst)
acc
(loop (rest lst) (+ (* (first lst) (first lst)) acc)))))
You must realize that both solutions share the same structure, what changes is:
We use + to combine the answers, instead of *
We square the current element (first lst) before adding it
The base case for adding a list is 0 (it was 1 for multiplication)
As a final comment, in a real application you shouldn't use explicit recursion, instead we would use higher-order procedures for composing our solution:
(define (square x)
(* x x))
(define (sum-squares lst)
(apply + (map square lst)))
Or even shorter, as a one-liner (but it's useful to have a square procedure around, so I prefer the previous solution):
(define (sum-squares lst)
(apply + (map (lambda (x) (* x x)) lst)))
Of course, any of the above solutions works as expected:
(sum-squares '())
=> 0
(sum-squares '(1 2 3))
=> 14
A more functional way would be to combine simple functions (sum and square) with high-order functions (map):
(define (square x) (* x x))
(define (sum lst) (foldl + 0 lst))
(define (sum-squares lst)
(sum (map square lst)))
I like Benesh's answer, just modifying it slightly so you don't have to traverse the list twice. (One fold vs a map and fold)
(define (square x) (* x x))
(define (square-y-and-addto-x x y) (+ x (square y)))
(define (sum-squares lst) (foldl square-y-and-addto-x 0 lst))
Or you can just define map-reduce
(define (map-reduce map-f reduce-f nil-value lst)
(if (null? lst)
nil-value
(map-reduce map-f reduce-f (reduce-f nil-value (map-f (car lst))))))
(define (sum-squares lst) (map-reduce square + 0 lst))
racket#> (define (f xs) (foldl (lambda (x b) (+ (* x x) b)) 0 xs))
racket#> (f '(1 2 3))
14
Without the use of loops or lamdas, cond can be used to solve this problem as follows ( printf is added just to make my exercises distinct. This is an exercise from SICP : exercise 1.3):
;; Takes three numbers and returns the sum of squares of two larger number
;; a,b,c -> int
;; returns -> int
(define (sum_sqr_two_large a b c)
(cond
((and (< a b) (< a c)) (sum-of-squares b c))
((and (< b c) (< b a)) (sum-of-squares a c))
((and (< c a) (< c b)) (sum-of-squares a b))
)
)
;; Sum of squares of numbers given
;; a,b -> int
;; returns -> int
(define (sum-of-squares a b)
(printf "ex. 1.3: ~a \n" (+ (square a)(square b)))
)
;; square of any integer
;; a -> int
;; returns -> int
(define (square a)
(* a a)
)
;; Sample invocation
(sum_sqr_two_large 1 2 6)

Distributive Law Simplification

I'm trying to write a procedure that makes use of the distributive property of an algebraic expression to simplify it:
(dist '(+ x y (exp x) (* x 5) y (* y 6)))
=> (+ (* x (+ 1 5))
(* y (+ 1 1 6))
(exp x))
(dist '(+ (* x y) x y))
=> (+ (* x (+ y 1))
y)
; or
=> (+ (* y (+ x 1))
x)
As the second example shows, there can be more than one possible outcome, I don't need to enumerate them all, just a valid one. I'm wondering if someone could provide me with at least a qualitative description of how they would start attacking this problem? Thanks :)
Oleg Kiselyov's pmatch macro makes distributing a factor across terms pretty easy:
(define dist
(λ (expr)
(pmatch expr
[(* ,factor (+ . ,addends))
`(+ ,#(map (λ (addend)
(list factor addend))
addends))]
[else
expr])))
(dist '(* 5 (+ x y))) => (+ (5 x) (5 y))
The main trick is to match a pattern and extract elements from the expression from the corresponding slots in the pattern. This requires a cond and let with tricky expressions to cdr to the right place in the list and car out the right element. pmatch writes that cond and let for you.
Factoring out common terms is harder because you have to look at all the subexpressions to find the common factors and then pull them out:
(define factor-out-common-factors
(λ (expr)
(pmatch expr
[(+ . ,terms) (guard (for-all (λ (t) (eq? '* (car t)))
terms))
(let ([commons (common-factors terms)])
`(* ,#commons (+ ,#(remove-all commons (map cdr terms)))))]
[else
expr])))
(define common-factors
(λ (exprs)
(let ([exprs (map cdr exprs)]) ; remove * at start of each expr
(fold-right (λ (factor acc)
(if (for-all (λ (e) (member factor e))
exprs)
(cons factor acc)
acc))
'()
(uniq (apply append exprs))))))
(define uniq
(λ (ls)
(fold-right (λ (x acc)
(if (member x acc)
acc
(cons x acc)))
'()
ls)))
(factor-out-common-factors '(+ (* 2 x) (* 2 y)))
=> (* 2 (+ (x) (y)))
The output could be cleaned up some more, this doesn't cover factoring out a 1, and remove-all is missing, but I'll leave all that to you.
A very general approach:
(dist expr var-list)
=> expr factored using terms in var-list
dist would have to know about "distributable" functions like +,-,*,/,etc and how each of them behave. If, say, it only knew about the first four, then :
(dist expr var-list
(if (empty? var-list) expr
(let* ([new-expr (factor expr (first var-list))])
(return "(* var " (dist new-expr (rest var-list)))))
That "return "(* var " " is not correct syntax, but you probably already knew that. I'm not a racket or lisp expert by any means, but basically this comes down to string processing? In any case, factor needs to be fleshed out so that it removes a single var from * functions and all of the var from + functions (replacing them with 1). It also needs to be smart enough to only do it when there are at least two replacements (otherwise we haven't actually done anything).

Resources