SICP Exercise 1.27
Question
Demonstrate that the Carmichael numbers listed in footnote 47 really do fool the Fermat test. That is, write a procedure that takes an integer \(n\) and tests whether \(a^n\) is congruent to \(a\) modulo \(n\) for every \(a\lt n\), and try your procedure on the given Carmichael numbers.
Answer
Here is my code. I added a few intentionally wrong numbers at the end to test for false positives.
(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 (try-it a n)
(cond ((= a (expmod a n n)) true)
(else false)))
(define (carmichael? n)
(define (try-carmichael n counter)
(cond ((= counter 0) true)
((try-it counter n) (try-carmichael n (- counter 1)))
(else false)))
(try-carmichael n (- n 1)))
(display "These should be true:") (newline)
(carmichael? 561)
(carmichael? 1105)
(carmichael? 1729)
(carmichael? 2465)
(carmichael? 2821)
(carmichael? 6601)
(display "These should be false:") (newline)
(carmichael? 100)
(carmichael? 34)
(carmichael? 2001)
(carmichael? 777)
And the results:
These should be true:
#t
#t
#t
#t
#t
#t
These should be false:
#f
#f
#f
#f