what's wrong with my higher order procedure? - scheme

I can't figure out why my lambda is wrong. It should create a make-exp.
(define (exp b n)
(if (n = 0)
1
(* b (exp b (- n 1)))))
(define make-exp (lambda(n) (lambda(b)(exp b n ))))
(define square (make-exp 2))
(square 3)
Error: 2 is not a function [square, exp, (anon)]

(n = 0)
This calls the function n with the arguments = and 0, except n is 2 and not a function, so this does not work. Presumably you meant (= n 0).

Related

Knuth-Morris-Pratt algorithm in Scheme

This is the code to calculate the failure function (how many steps we have to go back) in Scheme, when we use the Knuth-Morris-Pratt algorithm:
(define (compute-failure-function p)
(define n-p (string-length p))
(define sigma-table (make-vector n-p 0))
(let loop
((i-p 2)
(k 0))
(cond
((>= i-p n-p)
(vector-set! sigma-table (- n-p 1) k))
((eq? (string-ref p k)
(string-ref p (- i-p 1)))
(vector-set! sigma-table i-p (+ k 1))
(loop (+ i-p 1) (+ k 1)))
((> k 0)
(loop i-p (vector-ref sigma-table k)))
(else ; k=0
(vector-set! sigma-table i-p 0)
(loop (+ i-p 1) k))))
(vector-set! sigma-table 0 -1)
(lambda (q)
(vector-ref sigma-table q)))
But I do not understand the part when k > 0. Can someone explain it please?
I see you're confused with the syntax of a named let. This post does a good job explaining how it works, but perhaps an example with more familiar syntax will make things clearer. Take this code in Python, it adds all integers from 1 to 10:
sum = 0
n = 1
while n <= 10:
sum += n
n += 1
print(sum)
=> 55
Now let's try to write it in a recursive fashion, I'll call my function loop. This is completely equivalent:
def loop(n, sum):
if n > 10:
return sum
else:
return loop(n + 1, n + sum)
loop(1, 0)
=> 55
In the above example, the loop function implements an iteration, the parameter n is used to keep track of the current position, and the parameter sum accumulates the answer. Now let's write the exact same code, but in Scheme:
(let loop ((n 1) (sum 0))
(cond ((> n 10) sum)
(else (loop (+ n 1) (+ n sum)))))
=> 55
Now we've defined a local procedure called loop which is then automatically called with the initial values 1 and 0 for its parameters n and sum. When the base case of the recursion is reached, we return sum, otherwise we keep calling this procedure, passing updated values for the parameters. It's exactly the same as in the Python code! Don't be confused by the syntax.
In your algorithm, i-p and k are the iteration variables, which are initialized to 2 and 0 respectively. Depending on which condition is true, the iteration continues when we call loop again with updated values for i-p and k, or it ends when the case (>= i-p n-p) is reached, at this point the loop exits and the computed value is in the variable sigma-table. The procedure ends by returning a new function, referred to as the "failure function".

How would I go about create this function

How would I create an approximate cos function.
What I have so far.
(define k 0)
(define (approx-cos x n)
(cond
[(> 0 n) 0]
[else (* (/ (expt -1 k) (factorial (* 2 k))) (expt x (* 2 k)))]))
Your solution requires a lot of work before it meets the expectations. For starters, your parameters are switched: the first one is the number you want to calculate and the second one is the number of iterations...
Which leads me to the major problem in your solution, you're not iterating at all! You're supposed to call approx-cos at some point, or some helper procedure to do the looping (as I did).
Last but not least, you're not correctly implementing the formula. Where's the -1 part, for instance? Or where are you multiplying by x^2k? I'm afraid a complete rewrite is in order:
; main procedure
(define (approx-cos x n)
; call helper procedure
(loop 0 0 x n))
; define a helper procedure
(define (loop acc k x n)
; loop with k from 0 to n, accumulating result
(cond [(> k n) acc] ; return accumulator
[else
(loop (+ acc ; update accumulator
(* (/ (expt -1.0 k) ; implement the formula
(factorial (* 2.0 k)))
(expt x (* 2.0 k))))
(add1 k) ; increment iteration variable
x n)]))
This will pass all the check expects:
(approx-cos 0 0)
=> 1
(approx-cos (/ pi 2) 0)
=> 1
(approx-cos 0 10)
=> 1
(approx-cos pi 10)
=> -0.9999999999243502
(approx-cos (* 3 (/ pi 2)) 9)
=> -1.1432910825361444e-05
(approx-cos 10 100)
=> -0.8390715290756897
Some final thoughts: your implementation of factorial is very slow, if you plan to do a larger number of iterations, your factorial will freeze the execution at some point.

Scheme function as parameter

the program is supposed to use
(define (sum f n)
(if (= n 0)
(f 1)
(+ (f n) (sum f (- n 1)))))
(define (harm-term k)
(/ 1 k))
(define (harm-sum n)
(sum (harm-term 1) n))
to create a function called harm-sum that calculates the sum of harmonic series. But I keep getting the error
application:
not a procedure;
expected a procedure that can be applied to arguments
given: 3
arguments...:
for the sum function.
(define (sum f n)
(if (= n 0)
(f 1)
(+ (f n) (sum f (- n 1)))))
(define (harm-term k)
(/ 1 k))
(define (harm-sum n)
(sum (harm-term 1) n))
The way that you are eventually calling sum is wrong because you call sum with (harm-term 1) as the parameter that you are expecting a function for. (harm-term 1) clearly evaluates to a 1.
This means that when it is used later in sum as the parameter f it makes no sense (i.e. you eventually call (1 1))
You should be doing something like this:
(define (sum f n)
(if (= n 0)
(f 1)
(+ (f n) (sum f (- n 1)))))
(define (harm-term k)
(/ 1 k))
(define (harm-sum n)
(sum harm-term n)) ; the difference is the function itself is passed instead of the value the function returns for 1

Scheme Binomial function using Pascal's Triangle

The binom procedure is suppose to return a function such that ((binom n) k a b) is the kth term in the binomial expansion of (a + b)^n.
This is my code.
(define (pascal row col)
(cond ((= col 1) 1)
((= row col) 1)
(else (+ (pascal (- row 1) (- col 1)) (pascal (- row 1) col)))))
(define (binom n)
(lambda (k a b)
(cond ((or (= n 0) (= n k)) 1)
(else (binom (pascal k n)))) 1))
I am trying to fix the binom function. I think the formula is (n k) * a^k * b^(n-k). How should I write it in Scheme?
I think you got confused with the formulas, you're mixing up n, k, row and col.
I'd recommend writing down the formulas you want to program, name the variables on paper, then write the procedure using the same variable names.
With binom though, I'm not sure what your intent was.
Binom returns a lambda, that's all well and good.
But then in that lambda you make a recursive call to binom,
again returning a lambda? And then at the very end you basically ignore
the result you get from this and return 1?
In its current form binom will never return anything other than a lambda or 1.
Here's what I think you want:
(define (pascal n k)
(cond ((< n k) (error "not defined: k > n"))
((= k 1) n)
((= k 0) 1)
((= n k) 1)
(else (+ (pascal (- n 1) (- k 1)) (pascal (- n 1) k)))))
(define (binom n i a b)
(* (pascal n i) (expt a (- n i)) (expt b i)))

+: expects type <number> as 2nd argument, given: #<void>;

I'm currently working on exercise 1.29 of SICP, and my program keeps giving me the following error:
+: expects type <number> as 2nd argument, given: #<void>; other arguments were: 970299/500000
Here's the code I'm running using racket:
(define (cube x)
(* x x x))
(define (integral2 f a b n)
(define (get-mult k)
(cond ((= k 0) 1)
((even? k) 4)
(else 2)))
(define (h b a n)
(/ (- b a) n))
(define (y f a b h k)
(f (+ a (* k (h b a n)))))
(define (iter f a b n k)
(cond ((> n k)
(+ (* (get-mult k)
(y f a b h k))
(iter f a b n (+ k 1))))))
(iter f a b n 0))
(integral2 cube 0 1 100)
I'm guessing the "2nd argument" is referring to the place where I add the current iteration and future iterations. However, I don't understand why that second argument isn't returning a number. Does anyone know how to remedy this error?
"2nd argument" refers to the second argument to +, which is the expression (iter f a b n (+ k 1)). According to the error message, that expression is evaluating to void, rather than a meaningful value. Why would that be the case?
Well, the entire body of iter is this cond expression:
(cond ((> n k)
(+ (* (get-mult k)
(y f a b h k))
(iter f a b n (+ k 1)))))
Under what circumstances would this expression not evaluate to a number? Well, what does this expression do? It checks if n is greater than k, and in that case it returns the result of an addition, which should be a number. But what if n is less than k or equal to k? It still needs to return a number then, and right now it isn't.
You're missing an else clause in your iter procedure. Ask yourself: what should happen when (<= n k) ? It's the base case of the recursion, and it must return a number, too!
(define (iter f a b n k)
(cond ((> n k)
(+ (* (get-mult k)
(y f a b h k))
(iter f a b n (+ k 1))))
(else <???>))) ; return the appropriate value

Resources