definition of task : i have to make pumpkins and fishes hanging on a string
terms used :
what-is-it? ==>a function that determines whether to make a fish or a pumpkin
fish-squared ==> a function to make a fish using 2 parameters
pumpkin ==> a function to make a pumpkin with also 2 parameters
decorations ==> a function that appends all the images together
hang-by-thread ==> a function that hangs all the images to a thread
extra
for this exercise i have to use"(if (odd? k) fish-square pumpkin))" EXACTLY like that
problem
when i execute my program it takes a while and then crashes, so i suspect it of being trapped in a loop
code :
(define (fun-string n r)
(define (what-is-it k)
(if (odd? k) fish-squared pumpkin))
(define (decorations k)
(ht-append ((what-is-it k) r r)
(decorations (- k 1))))
(hang-by-thread (decorations n)))
goal :
the goal of this exercise is to learn how to pass-trough functions as parameters, something that scheme is able to do.
many thanks
EDIT*
i have added the base line, still the same problem, here is all the code :
(define (lampion r l)
(vc-append (filled-rectangle 2 l) (pumpkin r)))
(define (hang-by-string pumpkins)
(vc-append (filled-rectangle (pict-width pumpkins) 2)
lampionnetjes))
(define (fish-square wh l)
(vc-append (filled-rectangle 2 l) (fish wh wh)))
(define (fun-string n r)
(define (what-is-it k)
(if (odd? k) fish-square pumpkin))
(define (decorations k)
(if (= k 1) fish-square)
(ht-append ((what-is-it k) r r)
(decorations (- k 1))))
(hang-by-string (decorations n)))
Looks like you are missing the base case in procedure decorations. You should test whether k <= 0, and stop.
You haven't implemented uselpa's suggestion by doing
(define (decorations k)
(if (= k 1) fish-square) ; the results of this line are discarded
(ht-append ((what-is-it k) r r)
(decorations (- k 1))))
because you discard the result so of the if statement and return the value of
(ht-append ((what-is-it k) r r)
(decorations (- k 1)))
just like in the original code. The conditional has the form
(if test
then-part
else-part)
so what you need is
(define (decorations k)
(if (= k 1)
fish-square
(ht-append ((what-is-it k) r r)
(decorations (- k 1)))))
Related
"Use your partial sum function and the sequence in 3a to produce a stream containing successive
approximations to sin(x)"
I'm assuming the question is for me to have the value return, however, the output is "#< stream >" instead. What is wrong with my code or what am I missing?
my code for the said 3a is:
(define (sin-stream x)
(define(fact n)
(if (= n 1)
1
(* n (fact (- n 1)))))
(define (sign k)
(if (even? k)
1 -1))
(define (sin-str-term x k)
(/ (* (sign k)
(expt x (+ (* 2 k) 1)))
(fact (+ (* 2 k) 1))))
(define (sin-helper x k)
(stream-cons (sin-str-term x k)
(sin-helper x (+ k 1))))
(sin-helper x 0))
and the code I used for the partial sum function is:
(define (partial-sums s)
(stream-cons (stream-car s)
(add-streams (stream-cdr s) (partial-sums s))))
and the code I use to call the sin approximation is:
(define (sin-approx x)
(partial-sums (sin-stream x)))
The stream can't be displayed directly because it's an infinite object.
What you might want to do is implement a function stream->list or stream-take that takes a stream and a number and returns that many elements from the stream.
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)))
I must write a Scheme predicate that computes the function f(N -> N) defined as :
if n < 4 :f(n)= (n^2) + 5
if n ≥ 4 :f(n) = [f(n−1) + f(n−2)] * f(n−4)
I wrote a simple predicate that works :
(define functionfNaive
(lambda (n)
(if (< n 4) (+ (* n n) 5)
(* (+ (functionfNaive (- n 1)) (functionfNaive (- n 2)))
(functionfNaive (- n 4))))))
Now, I try a method with an accumulator but it doesn't work...
My code :
(define functionf
(lambda(n)
(functionfAux n 5 9 14)))
(define functionfAux
(lambda (n n1 n2 n4)
(cond
[(< n 4) (+ (* n n) 5)]
[(= n 4) (* n1 (+ n2 n4))]
[else (functionfAux (- n 1) n2 n4 (* n1 (+ n2 n4)))])))
As requested, here's a memoized version of your code that performs better than the naïve version:
(define functionf
(let ((cache (make-hash)))
(lambda (n)
(hash-ref!
cache
n
(thunk
(if (< n 4)
(+ (* n n) 5)
(* (+ (functionf (- n 1)) (functionf (- n 2))) (functionf (- n 4)))))))))
BTW... computing the result for large values of n is very quick, but printing takes a lot of time. To measure the time, use something like
(time (functionf 50) 'done)
AND here's a generic memoize procedure, should you need it:
(define (memoize fn)
(let ((cache (make-hash)))
(λ arg (hash-ref! cache arg (thunk (apply fn arg))))))
which in your case could be used like
(define functionf
(memoize
(lambda (n)
(if (< n 4)
(+ (* n n) 5)
(* (+ (functionf (- n 1)) (functionf (- n 2))) (functionf (- n 4)))))))
First, that's not a predicate. A Predicate is a function which returns a Boolean value.
To calculate the nth result, start with the first four and count up, maintaining the last four known elements. Stop when n is reached:
(define (step a b c d n)
(list b c d (* (+ c d) a)) (+ n 1)))
etc. Simple. The first call will be (step 5 6 9 14 3).
The depth of the recursion tree may be the biggest question, so may be use the iteration which means use some variables to memory the intermediate processes.
#lang racket
(define (functionf n)
(define (iter now n1 n2 n3 n4 back)
(if (= n now)
back
(iter (+ now 1) back n1 n2 n3 (* n3 (+ back n1)))))
(if (< n 4)
(+ 5 (* n n))
(iter 4 14 9 6 5 125)))
(functionf 5)
in this way, the depth of the stack only be 1 and the code is speeded up.
I have a problem with my Racket programm.
I want to add this function to my programm but I get stuck in my recursion:
Here the function:
ggt: N x N -> N
(m,n) ->
ggT(m-n,n) if m > n
ggT(m,n-m) if n > m
m if m=n
(define (ggT m n)
(cond
[(> m n)(ggT (- m n)] ;; If m > n the programm should go recursiv back and change
;; the value of m to m-n. But I know that this wont work this way
[(< m n)(ggT (- n m)] ;; Same Problem here
[else m]))
How do I start a real recursion?
Try this:
(define (ggT m n)
(cond [(> m n) (ggT (- m n) n)]
[(< m n) (ggT m (- n m))]
[else m]))
You just have to pass the parameters in the correct order when calling the ggT function, remember that ggT receives two parameters, but you were passing only one.
Your function ggT takes two parameters, but you are only passing 1 in. I think you want something like this:
(define (ggT m n)
(cond
[(> m n)(ggT (- m n) n)]
[(< m n)(ggT m (- n m))]
[else m]))
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