Skip to content

1.23

; The `smallest-divisor` procedure shown at the start 
; of this section does lots of needless testing: After 
; it checks to see if the number is divisible by 2 there 
; is no point in checking to see if it is divisible by any 
; larger even numbbers. This suggests that the values 
; used for test-divisor should not be 2, 3, 4, 5, 6, . . ., 
; but rather 2, 3, 5, 7, 9, . . ..
; To implement this change, define a procedure next that 
; returns 3 if its input is equal to 2 and otherwise returns 
; its input plus 2. Modify the smallest-divisor procedure 
; to use (next test-divisor) instead of (+ test-divisor 1). 
; With timed-prime-test incorporating this modified version 
; of smallest-divisor, run the test for each of the 12 primes 
; found in Exercise 1.22. Since this modification halves the 
; number of test steps, you should expect it to run about twice as fast. 
; Is this expectation confirmed? If not, what is the observed ratio
; of the speeds of the two algorithms, and how do you explain the 
; fact that it is different from 2?
(define (divides? a b) (= (remainder b a) 0))
(define (prime? n)
    (define (smallest-divisor n) (find-divisor n 2))
    (define (find-divisor n test-divisor)
        (cond ((> (square test-divisor) n) n)
              ((divides? test-divisor n) test-divisor)
              (else (find-divisor n (next test-divisor)))))
    (= n (smallest-divisor n))
)
(define (next n)
  (if (= n 2)
      3
      (+ n 2)))
; Timed prime test
(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))

; 12 primes found in `Exercise 1.22`
(timed-prime-test 1000000007)    ; .03
(timed-prime-test 1000000009)    ; .03
(timed-prime-test 1000000021)    ; .04000000000000001
(timed-prime-test 10000000019)   ; .08999999999999997
(timed-prime-test 10000000033)   ; .09000000000000002
(timed-prime-test 10000000061)   ; .08999999999999997
(timed-prime-test 100000000003)  ; .27 
(timed-prime-test 100000000019)  ; .30000000000000004
(timed-prime-test 100000000057)  ; .28
(timed-prime-test 1000000000039) ; 1.0399999999999998
(timed-prime-test 1000000000061) ; .8500000000000001
(timed-prime-test 1000000000063) ; .8600000000000003

; Comparing the order v/s time from previous and current
; implementations
; ------------------------------------------------
; | Order  | Previous | Current | Factor reduced |
; |----------------------------------------------|
; |  10^9  |   0.06   |  0.04   |    1.5         |
; |  10^10 |   0.16   |  0.9    |    1.77        |
; |  10^11 |   0.5    |  0.3    |    1.66        |
; |  10^12 |   1.45   |  0.85   |    1.7         |
; |----------------------------------------------|
;
; As we observe, factor reduced is not exactly 2, but ~1.5-1.6
; This is because, we spend some time during IF condition
; present in `next` procedure