non-residue_pseudoprimes.pl 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/usr/bin/perl
  2. # Smallest "non-residue" pseudoprime to base prime(n).
  3. # https://oeis.org/A307809
  4. # Interesting fact:
  5. # 4398575137518327194521 is a Fermat pseudoprime for b in [2, 58].
  6. use 5.020;
  7. use ntheory qw(:all);
  8. use experimental qw(signatures);
  9. use Math::GMPz;
  10. my @primes = @{primes(100)};
  11. sub least_nonresidue_odd ($n) { # for odd n
  12. my @factors = map { $_->[0] } factor_exp($n);
  13. foreach my $p (@primes) {
  14. (vecall { kronecker($p, $_) == 1 } @factors) || return $p;
  15. }
  16. return 101;
  17. }
  18. sub least_nonresidue_sqrtmod ($n) { # for any n
  19. foreach my $p (@primes) {
  20. sqrtmod($p, $n) // return $p;
  21. }
  22. return 101;
  23. }
  24. my %table;
  25. while (<>) {
  26. next if /^\h*#/;
  27. /\S/ or next;
  28. my $n = (split(' ', $_))[-1];
  29. $n || next;
  30. next if length($n) > 25;
  31. my $q = qnr($n);
  32. $n = Math::GMPz->new($n);
  33. if (exists $table{$q}) {
  34. next if ($table{$q} < $n);
  35. }
  36. if (powmod($q, ($n - 1) >> 1, $n) == $n - 1) {
  37. $table{$q} = $n;
  38. my $k = prime_count($q);
  39. say "a($k) <= $n";
  40. }
  41. }
  42. say "\nFinal results:";
  43. foreach my $k (sort { $a <=> $b } keys %table) {
  44. my $n = prime_count($k);
  45. printf("a(%2d) <= %s\n", $n, $table{$k});
  46. }
  47. __END__
  48. a( 1) <= 3277
  49. a( 2) <= 3281
  50. a( 3) <= 121463
  51. a( 4) <= 491209
  52. a( 5) <= 11530801
  53. a( 6) <= 512330281
  54. a( 7) <= 15656266201
  55. a( 8) <= 139309114031
  56. a( 9) <= 7947339136801
  57. a(10) <= 72054898434289
  58. a(11) <= 334152420730129
  59. a(12) <= 17676352761153241
  60. a(13) <= 172138573277896681
  61. # Very nice upper-bound:
  62. a(14) <= 4398575137518327194521