In Dr. Racket, how to write a Tetration function - recursion

How would I write a Tetration function in Dr. Racket.
This is my code so far:
(define (awesome-tetration k p)
(cond
[(= p 1) (expt k p)]
[else (expt (awesome-tetration k (sub1 p)) (expt k p))]))
If I input
(awesome-tetration 2 3)
My desired output is 2^2^2= 16
However, instead I get:
4294967296
Why is this happening. Can I get some pointers on what's wrong with my code. Thanks.

The recursive step is in correct, you're calling expt more times than needed. The solution is simpler, you just need to to this:
(define (awesome-tetration k p)
(cond
[(= p 1) (expt k p)]
[else (expt k (awesome-tetration k (sub1 p)))]))
Now it works:
(awesome-tetration 2 3)
=> 16

Related

Recursive call in Scheme language

I am reading sicp, there's a problem (practice 1.29), I write a scheme function to solve the the question, but it seems that the recursive call of the function get the wrong answer. Really strange to me. The code is following:
(define simpson
(lambda (f a b n)
(let ((h (/ (- b a) n))
(k 0))
(letrec
((sum (lambda (term start next end)
(if (> start end)
0
(+ (term start)
(sum term (next start) next end)))))
(next (lambda (x)
(let ()
(set! k (+ k 1))
(+ x h))))
(term (lambda (x)
(cond
((= k 0) (f a))
((= k n) (f b))
((even? k) (* 2
(f x)))
(else (* 4
(f x)))))))
(sum term a next b)))))
I didn't get the right answer.
For example, if I try to call the simpson function like this:
(simpson (lambda (x) x) 0 1 4)
I expected to get the 6, but it returned 10 to me, I am not sure where the error is.It seems to me that the function "sum" defined inside of Simpson function is not right.
If I rewrite the sum function inside of simpson using the iteration instead of recursive, I get the right answer.
You need to multiply the sum with h/3:
(* 1/3 h (sum term a next b))

Write in Scheme a recursive function to compute the Euler's number e

Write in Scheme a recursive function er, and a non-recursive (based on do-loop) function ei, that take as their argument the number of components n, and compute the following sum (approximation of e) 1 + 1/1! + 1/2! + 1/3! + ... + 1/n!, n>0
I have a solution for you. I hope that will help you!
((lambda (s) (s s -1 1 0))
(lambda (hep M f! euler-number)
((lambda (s)
(if (= M 20)
(+ 0.0 euler-number)
(s s 1 1 (+ euler-number (/ 1 f!)))))
(lambda (hop N x! euler)
(hep hop (+ N 1) (* x! N) euler)))))
First thing you have to do is to calculate the factorial, since you are going to need need in the for loop. Then, in the for loop you have to call the factorial function and please see how to do it with a for loop, instead of recursively. The last line of the post below is how to test for the function, which should return the correct number for the factorial of 6.
(define (factorial n)
(cond
((= n 0) 1)
((* n (factorial (- n 1))))))
(define (ei n)
(define sum 0)
(do ((i 0 (+ 1 i)))
((> i n))
(set! sum (+ sum (/ 1. (factorial i)))))
sum)
;(ei 6)

Building the built-in procedure "build-list" in Racket

I am trying to build the built-in procedure build-list in Racket.
The built-in function works like this:
(build-list 10 (lambda (x) (* x x)))
>> '(0 1 4 9 16 25 36 49 64 81)
My implementation is a recursive definition for a recursive procedure:
(define (my-build-list-recur list-len proc)
(if (= list-len 0)
'()
(cons (proc (sub1 list-len)) (my-build-list-recur (sub1 list-len) proc))))
When I call my implementation, I have:
(my-build-list-recur 10 (lambda (x) (* x x)))
>> '(81 64 49 36 25 16 9 4 1 0)
As you might have seen, I get the same result, but in a reverse order.
What can I do to have the result in the same order as the native function?
P.S.: I have done an implementation using a recursive definition for an iterative procedure which works perfectly. I am struggling now to generate the same result with the totally recursive procedure. I already know how to solve this doubt with long tail recursion.
This is my implementation with long tail recursion:
(define (my-build-list list-len proc)
(define (iter list-len accu n)
(if (= (length accu) list-len)
(reverse accu)
(iter list-len (cons (proc n) accu) (add1 n))))
;(trace iter)
(iter list-len '() 0))
Ok so you're looking for an answer that does not use state variables and a tail call. You want for a recursive procedure that also evolves a recursive process. Not sure why you want this other than just to see how the definition would differ. You should also read about tail recursion modulo cons (here, and on wikipedia) – it's relevant to this question.
;; recursive procedure, recursive process
(define (build-list n f)
(define (aux m)
(if (equal? m n)
empty
(cons (f m) (aux (add1 m)))))
(aux 0))
(build-list 5 (λ (x) (* x x)))
;; => '(0 1 4 9 16)
Notice how the aux call is no longer in tail position – ie, cons cannot finish evaluating until it has evaluated the aux call in its arguments. The process will look something like this, evolving on the stack:
(cons (f 0) ...)
(cons (f 0) (cons (f 1) ...))
(cons (f 0) (cons (f 1) (cons (f 2) ...)))
(cons (f 0) (cons (f 1) (cons (f 2) (cons (f 3) ...))))
(cons (f 0) (cons (f 1) (cons (f 2) (cons (f 3) (cons (f 4) ...)))))
(cons (f 0) (cons (f 1) (cons (f 2) (cons (f 3) (cons (f 4) empty)))))
(cons (f 0) (cons (f 1) (cons (f 2) (cons (f 3) (cons (f 4) '())))))
(cons (f 0) (cons (f 1) (cons (f 2) (cons (f 3) '(16)))))
(cons (f 0) (cons (f 1) (cons (f 2) '(9 16))))
(cons (f 0) (cons (f 1) '(4 9 16)))
(cons (f 0) '(1 4 9 16))
'(0 1 4 9 16)
You'll see that the cons calls are left hanging open until ... is filled in. And the last ... isn't filled in with empty until m is equal to n.
If you don't like the inner aux procedure, you can use a default parameter, but this does leak some of the private API to the public API. Maybe it's useful to you and/or maybe you don't really care.
;; recursive procedure, recursive process
(define (build-list n f (m 0))
(if (equal? m n)
'()
(cons (f m) (build-list n f (add1 m)))))
;; still only apply build-list with 2 arguments
(build-list 5 (lambda (x) (* x x)))
;; => '(0 1 4 9 16)
;; if a user wanted, they could start `m` at a different initial value
;; this is what i mean by "leaked" private API
(build-list 5 (lambda (x) (* x x) 3)
;; => '(9 16)
Stack-safe implementations
Why you'd specifically want a recursive process (one which grows the stack) is strange, imo, especially considering how easy it is to write a stack-safe build-list procedure which doesn't grow the stack. Here's some recursive procedures with a linear iterative processes.
The first one is extremely simple but does leak a little bit of private API using the acc parameter. You could easily fix this using an aux procedure like we did in the first solution.
;; recursive procedure, iterative process
(define (build-list n f (acc empty))
(if (equal? 0 n)
acc
(build-list (sub1 n) f (cons (f (sub1 n)) acc))))
(build-list 5 (λ (x) (* x x)))
;; => '(0 1 4 9 16)
Check out the evolved process
(cons (f 4) empty)
(cons (f 3) '(16))
(cons (f 2) '(9 16))
(cons (f 1) '(4 9 16))
(cons (f 0) '(1 4 9 16))
;; => '(0 1 4 9 16)
This is insanely better because it can constantly reuse one stack frame until the entire list is built. As an added advantage, we don't need to keep a counter that goes from 0 up to n. Instead, we build the list backwards and count from n-1 to 0.
Lastly, here's another recursive procedure that evolves a linear iterative process. It utilizes a named-let and continuation passing style. The loop helps prevent leaking the API this time.
;; recursive procedure, iterative process
(define (build-list n f)
(let loop ((m 0) (k identity))
(if (equal? n m)
(k empty)
(loop (add1 m) (λ (rest) (k (cons (f m) rest)))))))
(build-list 5 (λ (x) (* x x)))
;; => '(0 1 4 9 16)
It cleans up a little tho if you use compose and curry:
;; recursive procedure, iterative process
(define (build-list n f)
(let loop ((m 0) (k identity))
(if (equal? n m)
(k empty)
(loop (add1 m) (compose k (curry cons (f m)))))))
(build-list 5 (λ (x) (* x x)))
;; => '(0 1 4 9 16)
The process evolved from this procedure is slightly different, but you'll notice that it also doesn't grow the stack, creating a sequence of nested lambdas on the heap instead. So this would be sufficient for sufficiently large values of n:
(loop 0 identity) ; k0
(loop 1 (λ (x) (k0 (cons (f 0) x))) ; k1
(loop 2 (λ (x) (k1 (cons (f 1) x))) ; k2
(loop 3 (λ (x) (k2 (cons (f 2) x))) ; k3
(loop 4 (λ (x) (k3 (cons (f 3) x))) ; k4
(loop 5 (λ (x) (k4 (cons (f 4) x))) ; k5
(k5 empty)
(k4 (cons 16 empty))
(k3 (cons 9 '(16)))
(k2 (cons 4 '(9 16)))
(k1 (cons 1 '(4 9 16)))
(k0 (cons 0 '(1 4 9 16)))
(identity '(0 1 4 9 16))
'(0 1 4 9 16)

How to write the code so that car and list aren't in it?

Is there anyway to write the below code as to not have to make a list from which later on we have to car the element?
(define (square-it l)
(map (lambda (x) (* x x)) l))
(define (sum-it l)
(foldl + 0 l))
(define (sum-of-squares n)
(sum-it (square-it (numbers n))))
(define (square-of-sum n)
(square-it (*list* (sum-it (numbers n)))))
(- (*car* (square-of-sum 100)) (sum-of-squares 100))
As mentioned by #Sylwester, square-it is useful for squaring a list but not for squaring a single value, the inputs and outputs are different in each case, and sqr is the right procedure for squaring a single value. This should be enough to fix the problem:
(define (square-of-sum n)
(sqr (sum-it (numbers n))))
(- (square-of-sum 100) (sum-of-squares 100))
A simpler solution would be to use iterations and comprehensions and define each procedure independently. We can calculate the values directly over a range of values using only built-in procedures, there's no need to reinvent the wheel:
(define (sum-of-squares n)
(for/fold ([sum 0])
([i (in-range n)])
(+ sum (sqr i))))
(define (square-of-sum n)
(sqr (apply + (range n))))

Why Is This Tail-Recursive Function So Much More Complicated?

So, I'm fiddling with some basic maths, and I wanted a function to convert between bases.
I wrote this function:
(define (convert-base from to n)
(let f ([n n])
(if (zero? n)
n
(+ (modulo n to) (* from (f (quotient n to)))))))
Which works for all my personal tests < base 10 and would as far as I can imagine function perfectly fine for tests > base 10 if I just added support for additional digits.
What's confusing me is that when I tried to make the function tail-recursive, I ended up with this mess (I've added some spacing for SO's benefit, because my code is not often clear or pretty):
;e.g. 10 2 10 should output 1010, 10 8 64 should output 100 etc.
(define (convert-base-tail from to n)
(let f ([n n]
[acc 0]
[zeros 0])
(begin (printf "n is ~a. acc is ~a. zeros are ~a.\n" n acc zeros)
(cond [(zero? n) (let exp
([x acc]
[shft zeros])
(if (zero? shft)
x
(exp (* x 10) (- shft 1))))]
[(zero? (modulo n to))
(if (zero? acc)
(f (quotient n to) (* acc from) (add1 zeros))
(f (quotient n to) (* acc from) zeros))]
[else (f (quotient n to) (+ (* acc from) (modulo n to)) zeros )]))))
My question is, essentially, why is the tail-recursive function so much more complicated? Is it inevitable, due to the nature of the problem, or is it due to an oversight on my part?
It isn't, really:
(define (convert-base from to n)
(let f ([n n] [mul 1] [res 0])
(if (zero? n)
res
(f (quotient n to) (* mul from) (+ res (* mul (modulo n to)))))))
Testing
> (convert-base-y 10 2 10)
1010
> (convert-base-y 10 8 64)
100

Resources