super_poulet_pseudoprimes.pl 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. #!/usr/bin/perl
  2. # Least super-Poulet number (A050217) with n distinct prime factors.
  3. # https://oeis.org/A328665
  4. # Knwon terms:
  5. # 341, 294409, 9972894583, 1264022137981459, 14054662152215842621
  6. # Upper-bounds for larger values of n:
  7. # a(7) <= 1842158622953082708177091
  8. # a(8) <= 192463418472849397730107809253922101
  9. # a(9) <= 1347320741392600160214289343906212762456021
  10. # a(10) <= 70865138168006643427403953978871929070133095474701
  11. # a(11) <= 3363391752747838578311772729701478698952546288306688208857
  12. # a(12) <= 132153369641266990823936945628293401491197666138621036175881960329
  13. # a(13) <= 9105096650335639994239038954861714246150666715328403635257215036295306537
  14. use 5.020;
  15. use warnings;
  16. use experimental qw(signatures);
  17. use IO::Handle;
  18. use ntheory qw(forcomb forprimes divisors powmod);
  19. use Math::Prime::Util::GMP;
  20. sub super_poulet_pseudoprimes ($limit, $callback) {
  21. my %common_divisors;
  22. warn ":: Sieving...\n";
  23. forprimes {
  24. my $p = $_;
  25. foreach my $d (divisors($p - 1)) {
  26. #last if ($d == $p-1);
  27. if (powmod(2, $d, $p) == 1) {
  28. push @{$common_divisors{$d}}, $p;
  29. }
  30. }
  31. } $limit;
  32. warn ":: Creating combinations...\n";
  33. #foreach my $arr (values %common_divisors) {
  34. while (my ($key, $arr) = each %common_divisors) {
  35. my $nf = 8; # minimum number of prime factors
  36. next if @$arr < $nf;
  37. my $l = $#{$arr} + 1;
  38. foreach my $k ($nf .. $l) {
  39. forcomb {
  40. my $n = Math::Prime::Util::GMP::vecprod(@{$arr}[@_]);
  41. $callback->($n, $k);
  42. } $l, $k;
  43. }
  44. }
  45. }
  46. open my $fh, '>', 'psp_super_poulet_1.txt';
  47. $fh->autoflush(1);
  48. super_poulet_pseudoprimes(
  49. 1e7, # limit of the largest prime factor
  50. sub ($n, $k) {
  51. if ($n > ~0) { # report only numbers greater than 2^64
  52. warn "$k $n\n";
  53. say $fh "$k $n";
  54. }
  55. }
  56. );
  57. close $fh;