The first thing we learned was this simple notation:
(define (prime N) (Cond [(Or (= n 2) (= n 3)) #t] [(even N) #f] [Else (prime-test-loop N)])) (Define (prime-test-loop N) (Let (top (ceiling (sqrt N) )) (Let ITER (start 3)) (Cond [(> Start top) #t] [(= (mod n start) 0) #f] [Else (ITER (+ start 2)]))))
Although very clumsy, but in fact, it is "optimized", first of all, in addition to the number of even 2 is not judged. Second, the try-out iteration starts from 3, each time +2, also avoids the even. Finally, the end condition of the loop is (sqrt N).
Later, we see a method of generating the prime number sequence, the general idea is to maintain a known list of primes, each new number n is used in the list of known primes to try to remove. If neither is divisible, the n is a prime number, N is added to the known Prime number table, and the next iteration is entered. The original is implemented in C, with a large array in advance, each iteration iterates through the array, the known prime number of integer multiples of the corresponding array subscript are crossed out, and finally left in the array is the prime number. Here is the Scheme version I wrote:
(Define (prime-list N) (Let ITER (start 3) (Primes ' (2))) (Cond [(> Start N) primes] [(Andmap (Lambda (p) (Not (= (mod start p) 0)) primes) (ITER (+ start 2) (cons start primes)] [Else (ITER (+ Start 2) primes)]))
Later know that there is a probability-based detection method called Fermat inspection, SICP on the implementation of a Scheme:
(Define (square N) (* n N)) (Define (EXPMOD base exp m) (Cond (= exp 0) 1) (even exp) (MoD (square (expmod base (/exp 2) m ))) (Else (MoD (* Base (expmod base (-exp 1) 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) #t) ((fermat-test N) (fast-prime N (-times 1))) (else #f)))
This algorithm is very unreliable, because it is based on the theory is a pseudo-proposition, Fermat theorem asserts: If n is a prime number, then the n of any positive integer A is less than n to modulo n, the result is still a.
Its inverse proposition is that a is any positive integer less than n, if a ^ n% n = = A, then n is a prime number. Unfortunately, this inverse proposition does not hold, because there is a class number called Carmichael number, it conforms to a ^ n% n = = A This feature, but is not a prime. Using this program directly to check if a number is a prime has a big chance of making a mistake. This is part of the known Carmichael number:
561, 1105, 1729, 2465, 2821, 6601, 8911, 10585, 15841, 29341, 41041, 46657, 52633, 62745, 63973, 75361, 101101, 115921, 12 6217, 162401, 172081, 188461, 252601, 278545, 294409, 314821, 334153, 340561, 399001, 410041, 449065, 488881, 512461
As you can see, the minimum number is 561. If you're going to write a program that generates a list of primes, but it iterates over 500 times and starts babbling, the joke is a little bit bigger. SICP mentions a horse-testing variant, called Miller-rabin detection, which avoids the Carmichael of fools.
This detection is based on the assertion that if n is a prime number, A is any positive integer less than n, then a ^ (n-1)% n = = 1 N.
To test whether a number is prime with the Miller-Rabin detection algorithm, we should select a random positive integer less than n, and then use the Expmod function to calculate a ^ (n-1)% n. But when we go to square in expmod, we detect if we find a non-trivial square root of (1 N), in other words, see if there is a number, it is neither 1 nor n-1, but its square equals 1 n. It is easy to prove that if such a 1 non-trivial square root exists, then n is certainly not a prime number. It can also be proved that if n is an odd number that is not a prime number, at least half of the positive integers less than n can find this extraordinary square root when calculating a ^ (n-1) in this way.
The Chinese version of the SICP see not quite understand, I translate the English topic, still feel not quite understand. But probably the meaning understood that if a positive integer less than n is a, it conforms to a ^ (n-1) & n = = 1, but A is neither 1 nor n-1, then this n is definitely not a prime number. For a pseudo-prime, only one test, correct and wrong probability of half points, basic and fortune-telling almost. If you do two Tests, it's quite possible to find out what it really is. The more times you repeat, the more reliable the result. If repeated many times still pass the test, that this number n is probably really a prime. That's why it avoids the carmicheal number of fools.
SICP left a job. 1.28, requires the implementation of Miller-rabin detection, the following is the implementation:
(Define (EXPMOD base exp m) (Cond (= exp 0) 1) (even exp) (Check-nontrivial-sqrt (expmod base (/exp 2) m))) ;; Look here (Else mod (* Base (expmod base (-exp 1) m)))) (define (check-nontrivial-sqrt N m) ( (x (mod (square N) m)) ( if (and (Not (= n 1)) (not (= N (-M 1))) ( = x 1)) 0 x)) (define (miller-rabin-test N) ( define (try-it a) (= (Expmod A (-n 1) n) 1)) ( try-it (+ 1 (random (-N 1)))) (Define (fast-prime? n T IMEs) ( cond ((= times 0) #t) ((miller-rabin-test N) (fast-prime N (-times 1))) (Else #f)))
;; With a wrapper function, an even number doesn't have to be judged (define (prime N) (Cond (= n 2) #t) ( (even n) #f) (Else (fast-prime? n 20))))
Well, it was written, but the test found it was still gibberish ...
Then debug it when you are free.
On the detection of prime number