Evaluate the natural log e in Scheme - scheme

e=1/0!+1/1!+1/2!+1/3!……
I wrote the code like that, but whatever I input, it just returns 2....
Could you help me with that?
(define (fact n)
(if (= n 0)
1
(* n (- n 1))))
(define (e limit)
(if (= limit 0)
1
(+ (/ 1 (fact limit)) (e (- limit 1)))))

There's a mistake in the fact procedure:
(define (fact n)
(if (= n 0)
1
(* n (fact (- n 1))))) ; you forgot to recursively call `fact`
Test each procedure throughly, a simple unit test would have revealed that the problem was in fact and not in the e procedure.

Please tell me that this isn't for your homework, that you are just tinkering with Scheme. :)
I do not get 2 for any input to e. I get a divide-by-zero error for any input to e besides 0.
Setting that aside, you have a glaring problem in fact. Maybe the parentheses tripped you up and you have been staring at this too long:
(define (fact n)
(if (= n 0)
1
(* n (- n 1))))
...should be:
(define (fact n)
(if (= n 0)
1
(* n (fact (- n 1)))))
Remember, you can't implement a recursive function...without the function calling itself.
This should solve your problem.
Maybe TAs aren't available to help so quickly these days, but if this is for your homework, you need to work on breaking down the problems you encounter to the simplest elements to survive more programming, which will only get tougher. Specifically in this case, you needed to stop and ask whether fact, on which e depends, actually worked, find that it did not, and go from there.

Related

Scheme if expression returns '#<void>' if the body contains an expression

So I am currently reading SICP and I am stuck at exercise 1.22, since I do not understand why my program isn't working the way I intend it to work. Here is the Code
#lang sicp
; the given function to time the search for a prime
(define (timed-prime-test n)
(newline)
(display n)
(start-prime-test n (runtime)))
(define (start-prime-test n start-time)
(if (prime? n)
(report-prime (- (runtime) start-time))))
(define (report-prime elapsed-time)
(display " *** ")
(display elapsed-time))
; finds the smallest natural number that can divide n without any remainder
(define (smallest-divisor n)
(define (square x)
(* x x))
(define (divides? a b)
(= (remainder a b) 0))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? n test-divisor) test-divisor)
(else (find-divisor n (+ test-divisor 1)))))
(find-divisor n 2))
; returns true if the given number n is prime
(define (prime? n)
(= n (smallest-divisor n)))
; start searching at start and found keeps track of the amount of
; primes found, if it equals 3 return found
(define (search-for-primes start found)
(if (= found 3)
found ; after finding 3 primes above start return
((timed-prime-test start) ; if not continue search with start + 1
(search-for-primes (+ start 1) (if (not (prime? start))
found
(+ found 1))))))
(search-for-primes 1000 0)
The problem is that when I run this program it works fine until it finds a prime number. The interpreter that I use is racket and the program terminates with:
application: not a procedure;
expected a procedure that can be applied to arguments
given: #<void>
arguments...:
3
1019 *** 0
If I understand the interpreter correctly than it should evaluate this expression according to the applicative-order evaluation principle right? So why is it passing the if expression as a procedure to my search-for-primes procedure? What am I missing here?
The problem is in search-for-primes, if you have more than one expression in one of the legs of an if, then you need to put them inside a begin block - surrounding it with () won't work. This should fix the problem:
(define (search-for-primes start found)
(if (= found 3)
found
(begin ; add this!
(timed-prime-test start)
(search-for-primes (+ start 1) (if (not (prime? start))
found
(+ found 1))))))

Computing a series in racket

Ok, I'll start out by saying that this is a hw question. That being said, I'm not looking for the answer, just some direction to the answer.
I've got to compute a series up to n. My initial thoughts were to use recursion, and do something like the following
(define (series-b n)
(if (= n -1) 0 ; Not sure how to handle this
(+ (/ (expt -1 n) (factorial n)) (series-b (sub1 n)))
)
)
That seems to be the way to do this. However, I'm not really sure how to handle the -1 case, and that is throwing my expected answers off. Thanks in advance.
Edit
I do have some test cases, and they are as follows
n = 0: 1
n = 1: 1/2
n = 2: 2/3
n = 3: 5/8
n = 4: 19/30
n = 5: 91/144
I'm not entirely sure which series that is either.
Edit 2
I've selected soegaard's answer, however, I did make a small change to the final solution, which is:
(define (series-b n)
(for/sum ([i (+ n 1)])
(/ (expt -1 i)
(factorial (+ i 1))))
)
The accepted answer uses (factorial i) rather than (factorial (+ i 1)). I was not yet familiar with for/sum, but that is a really nice way to handle this problem, so thanks!
Your definitions seems right to me. The value of the empty sum is 0, so you are returning the correct value.
Your solution is the canonical one using recursion. An alternative using for/sum looks like this:
(define (series-c n)
(for/sum ([i (+ n 1)])
(/ (expt -1 i)
(factorial (+ i 1))))
You're doing well, and I think you're very close.
Start by writing a few test cases. Make sure to include test cases for the base case.
It's hard to answer the math part of the question, because I can't tell what series it is that you're computing!
You can implement this series as a SRFI 41 stream!
(require srfi/41)
(define negatives (stream-cons -1 (stream-map sub1 negatives)))
(define terms (stream-cons 1 (stream-map / terms (stream-cdr negatives))))
(define series (stream-cons 1 (stream-map + series (stream-cdr terms))))
Example usage:
> (stream->list 10 series)
(1 1/2 2/3 5/8 19/30 91/144 177/280 3641/5760 28673/45360 28319/44800)
Don't like streams? I like soegaard's answer, except that it has to recompute the factorial each time! I wish for/sum has the ability to hold "state" values the way for/fold does. Here's an implementation using for/fold:
(define (factorial-series n)
(define-values (sum _)
(for/fold ((sum 0) (value 1))
((i (in-range -2 (- -3 n) -1)))
(values (+ sum value)
(/ value i))))
sum)
Example usage:
> (map factorial-series (range 10))
(1 1/2 2/3 5/8 19/30 91/144 177/280 3641/5760 28673/45360 28319/44800)

Logarithmic runtime and tail recursion

In school, I have been learning about runtime and writing more efficient algorithms using tail recursion and the like, and a little while back an assignment asked us to consider the function for calculating powers;
(define (exp x n)
(if (zero? n) 1 (* x (exp x (- n 1)))))
and we were tasked with writing an exp function with a runtime O(log n), so this was my answer:
(define (exp x n)
(cond
((zero? n) 1)
((= 1 n) x)
((even? n) (exp (* x x) (/ n 2)))
(else (* x (exp (* x x) (/ (- n 1) 2))))))
which simply comes from x^2n = (x^2)^n and x^2n+1 = x*(x^2)^n.
So I have been trying to think of a way to implement tail recursion to even further optimize this function, but I can't really think of a way to do this.Back to my question, Is there any sort of rule of thumb to know when you can write a polynomial runtime algorithm as a logarithmic runtime?
I ask this, because, as easy as it was to write this in such a way that its runtime is logarithmic, I never would have thought to do it without having been specifically asked to do so.
Regarding the first part of your question: it's relatively simple to turn the procedure into tail-recursive form, we just have to pass an additional parameter to accumulate the answer. To avoid creating an additional procedure I'll use a named let:
(define (exp x n)
(let loop ([x x] [n n] [acc 1])
(cond
((zero? n) acc)
((= n 1) (* x acc))
((even? n) (loop (* x x) (/ n 2) acc))
(else (loop (* x x) (/ (- n 1) 2) (* x acc))))))
And for the second question: the rule of thumb would be - if there's a way to halve the size of a problem at some point when making the recursive call (in such a way that the result can be computed accordingly), then that's a good sign that it might exist a logarithmic solution for it. Of course, that's not always so obvious.

Not returning the answer i need

(define (checksum-2 ls)
(if (null? ls)
0
(let ([n 0])
(+ (+ n 1))(* n (car ls))(checksum-2 (cdr ls)))))
Ok, I have this code, its suppose to, if I wrote it right, the number (n) should increase by one every time it goes through the list, so n (in reality) should be like 1 2 3 4, but I want n to be multiplied by the car of the list.
Everything loads, but when the answer is returned I get 0.
Thanks!
If you format your code differently, you might have an easier time seeing what is going on:
(define (checksum-2 ls)
(if (null? ls)
0
(let ([n 0])
(+ (+ n 1))
(* n (car ls))
(checksum-2 (cdr ls)))))
Inside the let form, the expressions are evaluated in sequence but you're not using the results for any of them (except the last one). The results of the addition and multiplication are simply discarded.
What you need to do in this case is define a new helper function that uses an accumulator and performs the recursive call. I'm going to guess this is homework or a learning exercise, so I'm not going to give away the complete answer.
UPDATE: As a demonstration of the sort of thing you might need to do, here is a similar function in Scheme to sum the integers from 1 to n:
(define (sum n)
(define (sum-helper n a)
(if (<= n 0)
a
(sum-helper (- n 1) (+ a n))))
(sum-helper n 0))
You should be able to use a similar framework to implement your checksum-2 function.

weirdness in scheme

I was trying to implement Fermat's primality test in Scheme.
I wrote a procedure fermat2(initially called fermat1) which returns true
when a^p-1 congruent 1(mod p) (please read it correctly guys!!)
a
every prime p number should satisfy the procedure (And hence Fermat's little theorem .. )
for any a
But when I tried to count the number of times this procedure yields true for a fixed number of trials ... ( using countt procedure, described in code) I got shocking results ans
So I changed the procedure slightly (I don't see any logical change .. may be I'm blind) and named it fermat1(replacing older fermat1 , now old fermat1 ->fermat2) and it worked .. the prime numbers passed the test all the times ...
why on earth the procedure fermat2 called less number of times ... what is actually wrong??
if it is wrong why don't I get error ... instead that computation is skipped!!(I think so!)
all you have to do , to understand what I'm trying to tell is
(countt fermat2 19 100)
(countt fermat1 19 100)
and see for yourself.
Code:
;;Guys this is really weird
;;I might not be able to explain this
;;just try out
;;(countt fermat2 19 100)
;;(countt fermat1 19 100)
;;compare both values ...
;;did you get any error using countt with fermat2,if yes please specify why u got error
;;if it was because of reminder procedure .. please tell your scheme version
;;created on 6 mar 2011 by fedvasu
;;using mit-scheme 9.0 (compiled from source/microcode)
;; i cant use a quote it mis idents (unfriendly stack overflow!)
;;fermat-test based on fermat(s) little theorem a^p-1 congruent to 1 (mod p) p is prime
;;see MIT-SICP,or Algorithms by Vazirani or anyother number theory book
;;this is the correct logic of fermat-test (the way it handles 0)
(define (fermat1 n)
(define (tryout a x)
;; (display "I've been called\n")
(= (remainder (fast-exp a (- x 1)) x) 1))
;;this exercises the algorithm
;;1+ to avoid 0
(define temp (random n))
(if (= temp 0)
(tryout (1+ temp) n)
(tryout temp n)))
;;old fermat-test
;;which is wrong
;;it doesnt produce any error!!
;;the inner procedure is called only selective times.. i dont know when exactly
;;uncomment the display line to see how many times tryout is called (using countt)
;;i didnt put any condition when it should be called
;;rather it should be every time fermat2 is called
;;how is it so??(is it to avoid error?)
(define (fermat2 n)
(define (tryout a x)
;; (display "I've been called\n")
(= (remainder (fast-exp a (- x 1)) x) 1))
;;this exercises the algorithm
;;1+ to avoid 0
(tryout (1+ (random n)) n))
;;this is the dependency procedure for fermat1 and fermat2
;;this procedure calculates base^exp (exp=nexp bcoz exp is a keyword,a primitive)
;;And it is correct :)
(define (fast-exp base nexp)
;;this is iterative procedure where a*b^n = base^exp is constant always
;;A bit tricky though
(define (logexp a b n)
(cond ((= n 0) a);;only at the last stage a*b^n is not same as base^exp
((even? n) (logexp a (square b) (/ n 2)))
(else (logexp (* a b) b (- n 1)))))
(logexp 1 base nexp))
;;utility procedure which takes a procedure and its argument and an extra
;; argument times which tells number of times to call
;;returns the number of times result of applying proc on input num yielded true
;;counting the number times it yielded true
;;procedure yields true for fixed input,
;;by calling it fixed times)
;;uncommenting display line will help
(define (countt proc num times)
(define (pcount p n t c)
(cond ((= t 0)c)
((p n );; (display "I'm passed by fermat1\n")
(pcount p n (- t 1) (+ c 1)));;increasing the count
(else c)))
(pcount proc num times 0))
I had real pain .. figuring out what it actually does .. please follow the code and tell why this dicrepieancies?
Even (countt fermat2 19 100) called twice returns different results.
Let's fix your fermat2 since it's shorter. Definition is: "If n is a prime number and a is any positive integer less than n, then a raised to the nth power is congruent to a modulo n.". That means f(a, n) = a^n mod n == a mod n. Your code tells f(a, n) = a^(n-1) mod n == 1 which is different. If we rewrite this according to definition:
(define (fermat2 n)
(define (tryout a x)
(= (remainder (fast-exp a x) x)
(remainder a x)))
(tryout (1+ (random n)) n))
This is not correct yet. (1+ (random n)) returns numbers from 1 to n inclusive, while we need [1..n):
(define (fermat2 n)
(define (tryout a x)
(= (remainder (fast-exp a x) x)
(remainder a x)))
(tryout (+ 1 (random (- n 1))) n))
This is correct version but we can improve it's readability. Since you're using tryout only in scope of fermat2 there is no need in parameter x to pass n - latter is already bound in scope of tryout, so final version is
(define (fermat n)
(define (tryout a)
(= (remainder (fast-exp a n) n)
(remainder a n)))
(tryout (+ 1 (random (- n 1)))))
Update:
I said that formula used in fermat2 is incorrect. This is wrong because if a*k = b*k (mod n) then a = b (mod n). Error as Vasu pointed was in generating random number for test.

Resources