Code Review
Compare your solutions
#| Для этого упражнения нет проверок.
Любое решение будет считаться успешным ответом. |#
; Необходимые процедуры
; !Важное уточнение! В связи с низкой точностью возвращаемого результата у runtime в реализации LISP'а от MIT, для получения видимого результата будет повторение 1000 раз. Изменена процедура start-prime-test
(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)
(newline)
(display n)
(start-prime-test n (runtime) 10))
(define (start-prime-test n start-time times)
(define (loop i k)
(if (= i k)
(report-prime (- (runtime) start-time))
(begin
(fast-prime? n times)
(loop (+ i 1) k))))
(if (fast-prime? n times)
(loop 1 1000)
#f))
(define (report-prime elapsed-time)
(display " *** ")
(display elapsed-time))
; Так как у теста Ферма порядок роста O(log n), то ожидаемое соотношение времени между проверкой на простоту поблизости от 1 000 000 и поблизости от 1000 будет (log 1000000) / (log 1000)
; По свойству логарифмов (log b) / (log a) = log_a(b), т. е. (log 1000000) / (log 1000) = log_1000(1000000) = 2
; Ожидаемое соотношение - 2
(timed-prime-test 1009) ; 1009 *** .26999999999999996
(timed-prime-test 1013) ; 1013 *** .3
(timed-prime-test 1019) ; 1019 *** .30000000000000004
; Среднее: 0.29
(timed-prime-test 10007) ; 10007 *** .32999999999999996
(timed-prime-test 10009) ; 10009 *** .33000000000000007
(timed-prime-test 10037) ; 10037 *** .31999999999999984
; Среднее: 0.32(6)
(timed-prime-test 100003) ; 100003 *** .3500000000000003
(timed-prime-test 100019) ; 100019 *** .3799999999999999
(timed-prime-test 100043) ; 100043 *** .3799999999999999
; Среднее: 0.37
(timed-prime-test 1000003) ; 1000003 *** .4200000000000004
(timed-prime-test 1000033) ; 1000033 *** .4299999999999997
(timed-prime-test 1000037) ; 1000037 *** .43999999999999995
(newline)
; Среднее: 0.43
; Отношение: 0.43 / 0.29 = 1.4828...
; Получившиеся данные не подтверждают наше предположение о соотношении. Это связано с особенностями самой процедуры runtime, "костылем" в 1000 запусков и, как следствие, лишние действия между самими операциями