1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 |
- (library (lib naive-prime-test)
- (export prime?)
- (import
- (except (rnrs base) let-values)
- (only (guile)
- lambda* λ
- remainder
- inexact->exact)
- (prefix (lib math) math:))
- ;; The biggest potential factor of a number is at maximum
- ;; its square root. Since we are looking for integer
- ;; factors, we also floor the square root. If it is even, we
- ;; substract 1, because even numbers cannot be prime
- ;; factors, except for 2.
- (define biggest-potential-factor
- (λ (num)
- (let ([near-sqrt (inexact->exact (floor (sqrt num)))])
- (cond
- [(= near-sqrt 2) near-sqrt]
- [(math:even? near-sqrt) (- near-sqrt 1)]
- [else near-sqrt]))))
- (define biggest-prime-factor
- (λ (num)
- (let iter ([fac (biggest-potential-factor num)])
- (cond
- ;; Stop looking for factors when reaching 1. This
- ;; prevents the search from going into negative
- ;; numbers towards negative infinity.
- [(= fac 1) 1]
- ;; If the number fac is really a factor of num and it
- ;; is prime, then that is the result.
- [(and (math:divides? fac num) (prime? fac)) fac]
- ;; 2 is the only even prime factor. If we reach 3, we
- ;; need to decrease by 1 only, so that we also test 2
- ;; as a prime factor.
- [(<= fac 3) (iter (- fac 1))]
- ;; Decrease by 2, to skip even numbers.
- [else (iter (- fac 2))]))))
- (define prime?
- (λ (num)
- (cond
- [(= num 0) #f]
- [(= num 1) #f]
- [(negative? num) #f]
- [else (= (biggest-prime-factor num) 1)]))))
|