pseudoprime_search.pl 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #!/usr/bin/perl
  2. use 5.020;
  3. use warnings;
  4. use strict;
  5. use ntheory qw(:all);
  6. use experimental qw(signatures);
  7. use List::Util qw(uniqnum);
  8. use File::Find qw(find);
  9. use Math::GMPz;
  10. use Math::AnyNum;
  11. use Math::Prime::Util::GMP qw(is_euler_pseudoprime);
  12. sub is_absolute_euler_pseudoprime ($n) {
  13. is_carmichael($n) and vecall { (($n-1)>>1) % ($_-1) == 0 } factor($n);
  14. }
  15. # Let b(n) be the smallest odd composite k such that q^((k-1)/2) == -1 (mod k) for every prime q <= prime(n).
  16. # b(1) = 3277
  17. # b(2) = 1530787
  18. # b(3) = 3697278427
  19. # b(4) = 118670087467
  20. # b(5) <= 2152302898747
  21. # b(6) <= 614796634515444067
  22. # b(7) <= 614796634515444067
  23. # 341, 1729, 1729, 46657
  24. my $N = 13;
  25. my $P = nth_prime($N);
  26. my $MAX = ~0;
  27. my @primes_bellow = @{primes($P)};
  28. #~ my $n = 1;
  29. #~ my $P = 2;
  30. my @primes = (2);
  31. sub non_residue {
  32. my ($n) = @_;
  33. foreach my $p (@primes) {
  34. #if ($p > $P) {
  35. # return -1;
  36. #}
  37. #sqrtmod($p, $n) // return $p;
  38. #sqrtmod($p, $n) // do { say "$p $n"; return $p};
  39. #kronecker($n, $p) == 1 and return $p;
  40. (vecall { kronecker($p, $_->[0]) == 1 } factor_exp($n)) || return $p;
  41. }
  42. return -1;
  43. }
  44. #~ foroddcomposites {
  45. #~ my $k = $_;
  46. #~ #if (powmod($q^((k-1)/2) == -1 and non_residue($k) == $P) {
  47. #~ if (powmod($P, ($k-1)>>1, $k) == $k-1) {
  48. #~ my $q = non_residue($k);
  49. #~ if ($q == $P) {
  50. #~ say $k;
  51. #~ $P = next_prime($P);
  52. #~ push @primes, $P;
  53. #~ exit if $P == 13;
  54. #~ }
  55. #~ }
  56. #~ } 1e9;
  57. #~ __END__
  58. sub isok {
  59. my ($k) = @_;
  60. if (powmod($P, ($k-1)>>1, $k) == $k-1) {
  61. my $q = non_residue($k);
  62. return ($P == $q);
  63. }
  64. return;
  65. #~ my $res;
  66. #~ my $p = nth_prime($n);
  67. #~ for(my $k = $A000229[$n-1]*$A000229[$n-1]; ; $k+=2) {
  68. #~ if (!is_prime($k) and powmod($p, ($k-1)>>1, $k) == $k-1) {
  69. #~ my $q = non_residue($k, $p);
  70. #~ if ($p == $q) {
  71. #~ return $k;
  72. #~ }
  73. #~ }
  74. #~ }
  75. #~ return $res;
  76. }
  77. #~ Found: 2095988771234401
  78. #~ Found: 35488761020833
  79. #~ Found: 4364724604902481
  80. #~ Found: 5087540155980241
  81. #~ Found: 619440406020833
  82. sub isok_12_may {
  83. my ($k) = @_;
  84. # Odd composite numbers n such that b^((n-1)/2) == +-1 (mod n) for every natural b < log(n).
  85. my $w = $k-1;
  86. my $z = $w>>1;
  87. my $upto = int(log("$k"));
  88. #~ if (lc($upto) eq 'inf') {
  89. #~ $upto = Math::AnyNum->new($k)->ilog;
  90. #~ }
  91. #for (my $p = 2; $p <= $upto; ++$p) {
  92. for(my $p = 2; $p <= $upto; $p = next_prime($p)) {
  93. my $t = powmod($p, $z, $k);
  94. ($t == 1) || ($t == $w) || return;
  95. }
  96. return 1;
  97. }
  98. #~ say isok_12_may(35488761020833);
  99. #~ say isok_12_may(2095988771234401);
  100. #~ say is_absolute_euler_pseudoprime(35488761020833);
  101. #~ __END__
  102. sub isok_12_may_stronger {
  103. my ($k) = @_;
  104. # Odd composite numbers n such that b^((n-1)/2) == +-1 (mod n) for every natural b < log(n).
  105. my $w = $k-1;
  106. my $z = $w>>1;
  107. my $upto = int(log("$k"));
  108. #~ if (lc($upto) eq 'inf') {
  109. #~ $upto = Math::AnyNum->new($k)->ilog;
  110. #~ }
  111. for(my $p = 2; $p <= $upto; $p = next_prime($p)) {
  112. my $t = powmod($p, $z, $k);
  113. ($t == 1) || return;
  114. }
  115. return 1;
  116. }
  117. #~ #foreach my $k(1..1e6) {
  118. #~ $| = 1;
  119. #~ #for (my $k = 3; $k <= 1e9; $k += 2) {
  120. #~ foroddcomposites {
  121. #~ my $k = $_;
  122. #~ #if (not is_prime($k) and isok($k)) {
  123. #~ if (isok($k)) {
  124. #~ print($k, ", ");
  125. #~ if (not isok_stronger($k)) {
  126. #~ die "Counter-example: $k";
  127. #~ }
  128. #~ }
  129. #~ } 1e9;
  130. #~ __END__
  131. sub isok_b {
  132. my ($k) = @_;
  133. #$k % 2 == 1 or return;
  134. vecall { powmod($_, ($k-1)>>1, $k) == $k-1 } @primes_bellow;
  135. }
  136. sub isok_b2 {
  137. my ($k) = @_;
  138. $k % 2 == 1 or return;
  139. vecall { powmod($_, ($k-1)>>1, $k) == 1 } 2..($P-1);
  140. }
  141. my %seen;
  142. sub process_file {
  143. my ($file) = @_;
  144. open my $fh, '<', $file;
  145. while (<$fh>) {
  146. next if /^\h*#/;
  147. /\S/ or next;
  148. my $n = (split(' ', $_))[-1];
  149. $n || next;
  150. #if ($n > $MAX or $n <= 2) {
  151. # next;
  152. #}
  153. #~ if (length($n) > 30) {
  154. #~ next;
  155. #~ }
  156. if ($n > 1.7 * 10**16) {
  157. next;
  158. }
  159. #if ($n > ~0) {
  160. #if (length($n) > 30) {
  161. # next;
  162. #}
  163. next if $seen{$n}++;
  164. if ($n > ~0) {
  165. $n = Math::GMPz->new("$n");
  166. }
  167. #next if is_prime($n);
  168. #if (isok_b($n)) {
  169. # if (not is_absolute_euler_pseudoprime($n) and isok_12_may($n) ) {
  170. if (isok_12_may($n) and not isok_12_may_stronger($n)) {
  171. say "Counter-example: $n";
  172. #$MAX = $n;
  173. # if (not isok_stronger($n)) {
  174. # die "Counter-example: $n";
  175. # }
  176. #~ if ($n < $MAX) {
  177. #~ $MAX = $n;
  178. #~ say "New record: $n";
  179. #~ }
  180. }
  181. }
  182. close $fh;
  183. }
  184. my $psp = "/home/swampyx/Other/Programare/experimental-projects/pseudoprimes/oeis-pseudoprimes";
  185. find({
  186. wanted => sub {
  187. if ( /\.txt\z/) {
  188. #say "Processing $_";
  189. process_file($_);
  190. }
  191. },
  192. no_chdir => 1,
  193. } => $psp);