The following program is designed to calculate base^expo mod m.
(define (expmod base expo m)
(define (square n)
(* n n))
(define (even? n)
(= (remainder n 2) 0))
(define (expmod-iter base expo m result)
(cond ((= expo 0) result)
((even? expo)
(expmod-iter base
(/ expo 2)
m
(remainder (square result) m)))
(else
(expmod-iter base
(- expo 1)
m
(remainder (* base result) m)))))
(expmod-iter base expo m 1))
In fact, I'm trying to convert a tail-recursive program from SICP to its iterative equivalent. Here is the original program:
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(remainder (square (expmod base (/ exp 2) m))
m))
(else
(remainder (* base (expmod base (- exp 1) m))
m))))
The result of (expmod 42 1000000007 1000000007) is 270001056, but according to Fermat's Little Theorem, since 1000000007 is prime, the result should be 42.
What am I doing wrong?
This is my implementation of an iterative expmod:
(define (expmod base exp mod)
(let loop ((base base)
(exp exp)
(result 1))
(cond ((zero? exp) result)
((odd? exp) (loop base (sub1 exp) (modulo (* result base) mod)))
(else (loop (modulo (sqr base) mod) (quotient exp 2) result)))))
Tested in Racket with your sample input. You'll need to replace sub1 and sqr with suitable implementations if you're not using Racket.
Note that, while you do have to square the base for an even exponent, you can actually mod the result of that, as you can see in my code. So it doesn't get too massive.
Related
(define (pow b n)
"YOUR-DOC-HERE"
(cond ((= n 0) 1)
((even? n) (pow (pow b (/ n 2)) 2))
((odd? n) (* b (pow (pow b (/ (- n 1) 2)) 2)))))
(define (pow b n)
"YOUR-DOC-HERE"
(cond ((= n 0) 1)
((even? n) (* (pow b (/ n 2)) (pow b (/ n 2))))
((odd? n) (* b (pow b (/ (- n 1) 2)) (pow b (/ (- n 1) 2))))))
Here are two versions of my code for a power function with logarithmic efficiency. However, the first function would have a maximum recursion depth exceeded error and the second, though works, doesn't seem to function at a required efficiency. I am new to Scheme and I wonder what's wrong with these implementations?
Your 1st version uses itself to square every value, which creates an infinite loop in the even? clause.
Your 2nd version calls pow twice in each clause which reverses any gain from the logarithmic algorithm.
Your can fix it using let like this:
(define (pow b n)
"Recursive power in logarithmic depth."
(let ((square (lambda (x) (* x x))))
(cond ((= n 0) 1)
((even? n) (square (pow b (/ n 2))))
((odd? n) (* b (square (pow b (/ (- n 1) 2))))))))
or like this:
(define (pow b n)
"Recursive power in logarithmic depth."
(cond ((= n 0) 1)
((even? n)
(let ((x (pow b (/ n 2))))
(* x x)))
((odd? n)
(let ((x (square (pow b (/ (- n 1) 2)))))
(* b x x)))))
(define m (expt 2 32))
(define a 22695477)
(define c 1.0)
(define (integers-starting-from n)
(stream-cons n (integers-starting-from (+ n 1))))
(define (prng seed)
(define xn (remainder (+ c (* a seed)) m))
(define prn (/ (remainder (+ c (* a seed)) m) m))
(stream-cons prn
(prng xn)))
When I run this code my current output is
(stream->list (prng 3) 5)
> (0.015852607786655426 0.4954120593611151 0.998752823099494 0.7253396362066269 0.03071586787700653)
But Output has to be
(stream->list (prng 3) 5)
> (0.01585 0.4954 0.9988 0.7253 0.0307)
How do I make output to ten-thousandth place value?
Here's one way, if you're using Racket:
(define (prng seed)
(define xn (remainder (+ c (* a seed)) m))
(define prn (/ (remainder (+ c (* a seed)) m) m))
(stream-cons (truncate prn 4)
(prng xn)))
(define (truncate num precision)
(string->number (~r num #:precision precision)))
Now the output will be:
'(0.0159 0.4954 0.9988 0.7253 0.0307)
I am working through SICP. In exercise 1.28 about the Miller-Rabin test. I had this code, that I know is wrong because it does not follow the instrcuccions of the exercise.
(define (fast-prime? n times)
(define (even? x)
(= (remainder x 2) 0))
(define (miller-rabin-test n)
(try-it (+ 1 (random (- n 1)))))
(define (try-it a)
(= (expmod a (- n 1) n) 1))
(define (expmod base exp m)
(cond ((= exp 0) 1)
((even? exp)
(if (and (not (= exp (- m 1))) (= (remainder (square exp) m) 1))
0
(remainder (square (expmod base (/ exp 2) m)) m)))
(else
(remainder (* base (expmod base (- exp 1) m)) m))))
(cond ((= times 0) true)
((miller-rabin-test n) (fast-prime? n (- times 1)))
(else false)))
In it I test if the square of the exponent is congruent to 1 mod n. Which according
to what I have read, and other correct implementations I have seen is wrong. I should test
the entire number as in:
...
(square
(trivial-test (expmod base (/ exp 2) m) m))
...
The thing is that I have tested this, with many prime numbers and large Carmicheal numbers,
and it seems to give the correct answer, though a bit slower. I don't understand why this
seems to work.
Your version of the function "works" only because you are lucky. Try this experiment: evaluate (fast-prime? 561 3) a hundred times. Depending on the random witnesses that your function chooses, sometimes it will return true and sometimes it will return false. When I did that I got 12 true and 88 false, but you may get different results, depending on your random number generator.
> (let loop ((k 0) (t 0) (f 0))
(if (= k 100) (values t f)
(if (fast-prime? 561 3)
(loop (+ k 1) (+ t 1) f)
(loop (+ k 1) t (+ f 1)))))
12
88
I don't have SICP in front of me -- my copy is at home -- but I can tell you the right way to perform a Miller-Rabin primality test.
Your expmod function is incorrect; there is no reason to square the exponent. Here is a proper function to perform modular exponentiation:
(define (expm b e m) ; modular exponentiation
(let loop ((b b) (e e) (x 1))
(if (zero? e) x
(loop (modulo (* b b) m) (quotient e 2)
(if (odd? e) (modulo (* b x) m) x)))))
Then Gary Miller's strong pseudoprime test, which is a strong version of your try-it test for which there is a witness a that proves the compositeness of every composite n, looks like this:
(define (strong-pseudoprime? n a) ; strong pseudoprime base a
(let loop ((r 0) (s (- n 1)))
(if (even? s) (loop (+ r 1) (/ s 2))
(if (= (expm a s n) 1) #t
(let loop ((r r) (s s))
(cond ((zero? r) #f)
((= (expm a s n) (- n 1)) #t)
(else (loop (- r 1) (* s 2)))))))))
Assuming the Extended Riemann Hypothesis, testing every a from 2 to n-1 will prove (an actual, deterministic proof, not just a probabilistic estimate of primality) the primality of a prime n, or identify at least one a that is a witness to the compositeness of a composite n. Michael Rabin proved that if n is composite, at least three-quarters of the a from 2 to n-1 are witnesses to that compositeness, so testing k random bases demonstrates, but does not prove, the primality of a prime n to a probability of 4−k. Thus, this implementation of the Miller-Rabin primality test:
(define (prime? n k)
(let loop ((k k))
(cond ((zero? k) #t)
((not (strong-pseudoprime? n (random (+ 2 (- n 3))))) #f)
(else (loop (- k 1))))))
That always works properly:
> (let loop ((k 0) (t 0) (f 0))
(if (= k 100) (values t f)
(if (prime? 561 3)
(loop (+ k 1) (+ t 1) f)
(loop (+ k 1) t (+ f 1)))))
0
100
I know your purpose is to study SICP rather than to program primality tests, but if you're interested in programming with prime numbers, I modestly recommend this essay at my blog, which discusses the Miller-Rabin test, among other topics. You should also know there are better (faster, less likely to report erroneous result) primality tests available than randomized Miller-Rabin.
It seems to me, you still got correct answer, because in each iteration of expmod you check conditions for previous iteration. You could try to debug exp value using display function inside expmod. Really, your code is not very different from this one.
I have written a simple procedure to find the divisors of a number (not including the number itself). I have figured out how to print them, but I would like to have this function return a list containing each of the divisors.
(define (divisors n)
(do ((i 1 (+ i 1)))
((> i (floor (/ n 2))))
(cond
((= (modulo n i) 0)
(printf "~a " i)))))
My idea is to create a local list, adding elements to it where my printf expression is, and then having the function return that list. How might I go about doing that? I am new to Scheme, and Lisp in general.
Do you necessarily have to use have to use do? here's a way:
(define (divisors n)
(do ((i 1 (add1 i))
(acc '() (if (zero? (modulo n i)) (cons i acc) acc)))
((> i (floor (/ n 2)))
(reverse acc))))
But I believe it's easier to understand if you build an output list with a named let:
(define (divisors n)
(let loop ((i 1))
(cond ((> i (floor (/ n 2))) '())
((zero? (modulo n i))
(cons i (loop (add1 i))))
(else (loop (add1 i))))))
Or if you happen to be using Racket, you can use for/fold like this:
(define (divisors n)
(reverse
(for/fold ([acc '()])
([i (in-range 1 (add1 (floor (/ n 2))))])
(if (zero? (modulo n i))
(cons i acc)
acc))))
Notice that all of the above solutions are written in a functional programming style, which is the idiomatic way to program in Scheme - without using mutation operations. It's also possible to write a procedural style solution (see #GoZoner's answer), similar to how you'd solve this problem in a C-like language, but that's not idiomatic.
Just create a local variable l and extend it instead of printing stuff. When done, return it. Like this:
(define (divisors n)
(let ((l '()))
(do ((i 1 (+ i 1)))
((> i (floor (/ n 2))))
(cond ((= (modulo n i) 0)
(set! l (cons i l))))
l))
Note that because each i was 'consed' onto the front of l, the ordering in l will be high to low. Use (reverse l) as the return value if low to high ordering is needed.
I found code for generating Sierpinski carpet at http://rosettacode.org/wiki/Sierpinski_carpet#Scheme - but it won't run in the DrRacket environment or WeScheme. Could someone provide solutions for either environments?
It looks like this code runs fine in DrRacket after prepending a
#lang racket
line indicating that the code is written in Racket. I can provide more detail if this is not sufficient.
I've translated the program to run under WeScheme. I've made a few changes: rather than use (display) and (newline), I use the image primitives that WeScheme provides to make a slightly nicer picture. You can view the running program and its source code. For convenience, I also include the source here:
;; Sierpenski carpet.
;; http://rosettacode.org/wiki/Sierpinski_carpet#Scheme
(define SQUARE (square 10 "solid" "red"))
(define SPACE (square 10 "solid" "white"))
(define (carpet n)
(local [(define (in-carpet? x y)
(cond ((or (zero? x) (zero? y))
#t)
((and (= 1 (remainder x 3)) (= 1 (remainder y 3)))
#f)
(else
(in-carpet? (quotient x 3) (quotient y 3)))))]
(letrec ([outer (lambda (i)
(cond
[(< i (expt 3 n))
(local ([define a-row
(letrec ([inner
(lambda (j)
(cond [(< j (expt 3 n))
(cons (if (in-carpet? i j)
SQUARE
SPACE)
(inner (add1 j)))]
[else
empty]))])
(inner 0))])
(cons (apply beside a-row)
(outer (add1 i))))]
[else
empty]))])
(apply above (outer 0)))))
(carpet 3)
Here is the modified code for WeScheme. WeScheme don't support do-loop syntax, so I use unfold from srfi-1 instead
(define (unfold p f g seed)
(if (p seed) '()
(cons (f seed)
(unfold p f g (g seed)))))
(define (1- n) (- n 1))
(define (carpet n)
(letrec ((in-carpet?
(lambda (x y)
(cond ((or (zero? x) (zero? y))
#t)
((and (= 1 (remainder x 3)) (= 1 (remainder y 3)))
#f)
(else
(in-carpet? (quotient x 3) (quotient y 3)))))))
(let ((result
(unfold negative?
(lambda (i)
(unfold negative?
(lambda (j) (in-carpet? i j))
1-
(1- (expt 3 n))))
1-
(1- (expt 3 n)))))
(for-each (lambda (line)
(begin
(for-each (lambda (char) (display (if char #\# #\space))) line)
(newline)))
result))))