naive-prime-test.scm 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. (library (naive-prime-test)
  2. (export prime?)
  3. (import
  4. (except (rnrs base) let-values)
  5. (only (guile)
  6. lambda* λ
  7. remainder
  8. inexact->exact))
  9. (define even?
  10. (λ (num)
  11. (= (remainder num 2) 0)))
  12. (define divides?
  13. (λ (num div)
  14. (= (remainder num div) 0)))
  15. ;; The biggest potential factor of a number is at maximum
  16. ;; its square root. Since we are looking for integer
  17. ;; factors, we also floor the square root. If it is even, we
  18. ;; substract 1, because even numbers cannot be prime
  19. ;; factors, except for 2.
  20. (define biggest-potential-factor
  21. (λ (num)
  22. (let ([near-sqrt (inexact->exact (floor (sqrt num)))])
  23. (cond
  24. [(= near-sqrt 2) near-sqrt]
  25. [(even? near-sqrt) (- near-sqrt 1)]
  26. [else near-sqrt]))))
  27. (define biggest-prime-factor
  28. (λ (num)
  29. (let iter ([fac (biggest-potential-factor num)])
  30. (cond
  31. ;; Stop looking for factors when reaching 1. This
  32. ;; prevents the search from going into negative
  33. ;; numbers towards negative infinity.
  34. [(= fac 1) 1]
  35. ;; If the number fac is really a factor of num and it
  36. ;; is prime, then that is the result.
  37. [(and (divides? num fac) (prime? fac)) fac]
  38. ;; 2 is the only even prime factor. If we reach 3, we
  39. ;; need to decrease by 1 only, so that we also test 2
  40. ;; as a prime factor.
  41. [(<= fac 3) (iter (- fac 1))]
  42. ;; Decrease by 2, to skip even numbers.
  43. [else (iter (- fac 2))]))))
  44. (define prime?
  45. (λ (num)
  46. (if (= num 1)
  47. #f
  48. (= (biggest-prime-factor num) 1)))))