fermat_overpseudoprimes_in_range.sf 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 04 September 2022
  4. # https://github.com/trizen
  5. # Generate all the k-omega Fermat overpseudoprimes in range [a,b]. (not in sorted order)
  6. # Definition:
  7. # k-omega primes are numbers n such that omega(n) = k.
  8. # See also:
  9. # https://en.wikipedia.org/wiki/Almost_prime
  10. # https://en.wikipedia.org/wiki/Prime_omega_function
  11. # https://trizenx.blogspot.com/2020/08/pseudoprimes-construction-methods-and.html
  12. func inverse_znorder_primes(base, lambda) is cached {
  13. base**lambda - 1 -> prime_divisors
  14. }
  15. func iterate_over_primes(x,y,base,lambda,callback) {
  16. if ((lambda > 1) && (lambda <= 100)) {
  17. for q in (inverse_znorder_primes(base, lambda)) {
  18. next if (q < x)
  19. break if (q > y)
  20. #znorder(base, q) == lambda || next
  21. callback(q)
  22. }
  23. return nil
  24. }
  25. if (lambda > 1) {
  26. var u = lambda*idiv_ceil(x-1, lambda)
  27. return nil if (u > y)
  28. for w in (range(u, y, lambda)) {
  29. with (w+1) { |p|
  30. callback(p) if p.is_prime
  31. }
  32. }
  33. return nil
  34. }
  35. each_prime(x, y, callback)
  36. }
  37. func fermat_overpseudoprimes_in_range(A, B, k, base, callback) {
  38. A = max(k.pn_primorial, A)
  39. func (m, lambda, lo, j) {
  40. var hi = idiv(B,m).iroot(j)
  41. if (lo > hi) {
  42. return nil
  43. }
  44. iterate_over_primes(lo, hi, base, lambda, {|p|
  45. next if p.divides(base)
  46. for (var (q,v) = (p, m*p); v <= B; (q,v) = (q*p, v*p)) {
  47. var L = znorder(base, q)
  48. if (lambda > 1) {
  49. lambda == L || break
  50. }
  51. v.is_coprime(L) || break
  52. if (j == 1) {
  53. v >= A || next
  54. k.is_one && v.is_prime && next
  55. L `divides` v-1 || next
  56. callback(v)
  57. next
  58. }
  59. __FUNC__(v, L, p+1, j-1)
  60. }
  61. })
  62. }(1, 1, 2, k)
  63. return callback
  64. }
  65. # Generate all the 3-omega Fermat overpseudoprimes to base 2 in range [1194649, 14325843000]
  66. var k = 3
  67. var base = 2
  68. var from = 1194649
  69. var upto = 14325843000
  70. say gather { fermat_overpseudoprimes_in_range(from, upto, k, base, { take(_) }) }.sort
  71. __END__
  72. [13421773, 464955857, 536870911, 1220114377, 1541955409, 2454285751, 3435973837, 5256967999, 5726579371, 7030714813, 8493511669, 8538455017, 8788016089, 10545166433, 13893138041]