1.24|

$ cd ~

SICP Exercise 1.24

This time prime? procedure has been replaced by fast-prime?.

(define (divides? a b)
  (= (remainder b a) 0))
(define (square x) (* x x))

(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))))

(define (fermat-test n)
  (define (try-it a)
    (= (expmod a n n) a))
  (try-it (+ 1 (random (- n 1)))))

(define (fast-prime? n times)
  (cond ((= times 0) true)
        ((fermat-test n) (fast-prime? n (- times 1)))
        (else false)))

(define (timed-prime-test n)
  (start-prime-test n (runtime)))

(define (start-prime-test n start-time)
  (if (fast-prime? n 5)
      (report-prime (- (runtime) start-time) n)))

(define (report-prime elapsed-time n)
  (display n)
  (display "***")
  (display elapsed-time)
  (newline))

(define (search-for-primes a b)
  (if (even? a) (search-for-primes (+ a 1) b)
      (cond ((< a b) (timed-prime-test a)
                     (search-for-primes (+ a 2) b)))))

Again, finding the primes:

> (timed-prime-test 1009)
1009***17
> (timed-prime-test 1013)
1013***17
> (timed-prime-test 1019)
1019***18
> (timed-prime-test 10007)
10007***24
> (timed-prime-test 10009)
10009***21
> (timed-prime-test 10037)
10037***24
> (timed-prime-test 100003)
100003***26
> (timed-prime-test 100019)
100019***27
> (timed-prime-test 100043)
100043***28
> (timed-prime-test 1000003)
1000003***29
> (timed-prime-test 1000033)
1000033***29
> (timed-prime-test 1000037)
1000037**31

The Fermat-test has \(\Theta (\log n)\) order of growth. From the above tests, it’s clear that the time taken for twice as many digits (\(10^3\) vs \(10^6\)) is roughly twice as much (17t vs 31t. This supports logarithmic growth.