prog.sf 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. #!/usr/bin/ruby
  2. # Smallest overpseudoprime to base 2 (A141232) with n distinct prime factors.
  3. # https://oeis.org/A353409
  4. # Known terms:
  5. # 2047, 13421773, 14073748835533
  6. # Upper-bounds:
  7. # a(5) <= 1376414970248942474729
  8. # a(6) <= 48663264978548104646392577273
  9. # a(7) <= 294413417279041274238472403168164964689
  10. # a(8) <= 98117433931341406381352476618801951316878459720486433149
  11. # a(9) <= 1252977736815195675988249271013258909221812482895905512953752551821
  12. # New terms confirmed (03 September 2022):
  13. # a(5) = 1376414970248942474729
  14. # a(6) = 48663264978548104646392577273
  15. # a(7) = 294413417279041274238472403168164964689
  16. func squarefree_fermat_overpseudoprimes_in_range(a, b, k, base, callback) {
  17. a = max(k.pn_primorial, a)
  18. func (m, lambda, p, k) {
  19. var y = idiv(b,m).iroot(k)
  20. if (k == 1) {
  21. var x = max(p, idiv_ceil(a, m))
  22. if (idiv(y-x, lambda) > prime_count(x, y)) {
  23. say "Sieving: #{[x,y]}" if (y-x > 1e6)
  24. each_prime(x, y, {|p|
  25. with (m*p - 1) {|t|
  26. if ((lambda `divides` t) && powmod(base, lambda, p).is_one && (lambda == znorder(base, p))) {
  27. callback(t+1)
  28. }
  29. }
  30. })
  31. return nil
  32. }
  33. var u = lambda*idiv_ceil(x-1, lambda)
  34. if (idiv(y-u, lambda) > 1e6) {
  35. say "Sieving: #{[u, y]} with L = #{lambda} -- #{idiv(y-u, lambda)}"
  36. }
  37. for w in (range(u, y, lambda)) {
  38. with (w+1) { |p|
  39. p.is_prime || next
  40. with (m*p - 1) {|t|
  41. if ((lambda `divides` t) && powmod(base, lambda, p).is_one && (lambda == znorder(base, p))) {
  42. callback(t+1)
  43. }
  44. }
  45. }
  46. }
  47. return nil
  48. }
  49. for(var r; p <= y; p = r) {
  50. r = p.next_prime
  51. p.divides(base) && next
  52. var L = znorder(base, p)
  53. ((lambda==1 || lambda==L) && m.is_coprime(L)) || next
  54. var t = m*p
  55. var u = idiv_ceil(a, t)
  56. var v = idiv(b, t)
  57. if (u <= v) {
  58. __FUNC__(t, L, r, k-1)
  59. }
  60. }
  61. }(1, 1, 2, k)
  62. return callback
  63. }
  64. func a(n) {
  65. var x = n.pn_primorial
  66. var y = 2*x
  67. loop {
  68. var arr = gather { squarefree_fermat_overpseudoprimes_in_range(x, y, n, 2, {|n| take(n) }) }
  69. if (arr) {
  70. return arr[0]
  71. }
  72. x = y+1
  73. y = 2*x
  74. }
  75. }
  76. for n in (2..100) {
  77. say "a(#{n}) = #{a(n)}"
  78. }
  79. __END__
  80. a(2) = 2047
  81. a(3) = 13421773
  82. a(4) = 14073748835533
  83. a(5) = 1376414970248942474729