super_poulet_pseudoprimes_with_generated_primes.pl 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. #!/usr/bin/perl
  2. # Generate Super-Poulet pseudoprimes to base 2, using prime factors bellow a certain limit.
  3. use 5.020;
  4. use warnings;
  5. use experimental qw(signatures);
  6. #use IO::Handle;
  7. use List::Util qw(uniq);
  8. use ntheory qw(:all);
  9. use Math::Prime::Util::GMP;
  10. sub super_poulet_pseudoprimes ($limit, $callback) {
  11. my %common_divisors;
  12. warn ":: Sieving...\n";
  13. forprimes {
  14. my $p = $_;
  15. #if ($p % 24 == 1 or $p % 24 == 13) {
  16. # if ($p % 24 == 1 or $p % 24 == 13) {
  17. my $z = znorder(2, $p);
  18. # if (2*$z < $limit) {
  19. foreach my $d (divisors($p - 1)) {
  20. #if (powmod(2, $d, $p) == 1) {
  21. if ($d % $z == 0) {
  22. #if ($p > 1e8) {
  23. # if (exists $common_divisors{$d}) {
  24. # push @{$common_divisors{$d}}, $p;
  25. # }
  26. #}
  27. #else {
  28. #my $from = int($limit/$d);
  29. #foreach my $k ($from .. $from + 100) {
  30. #foreach my $k(map{$_->[0]**$_->[1]}factor_exp($p-1)) {
  31. #if (exists($common_divisors{$d}) and scalar(@{$common_divisors{$d}}) >= 5) {
  32. if (exists $common_divisors{$d}) {
  33. foreach my $k (divisors($d)) {
  34. #for (my $k = $from;
  35. #foreach my $k (uniq(factor($p+1))) {
  36. #foreach my $j (3..10) {
  37. my $m = ($k + int rand 100);
  38. if (($d % 2) * ($m % 2) != 0) {
  39. ++$m;
  40. }
  41. my $q = $d*$m+1;
  42. #~ if (is_prime($q) and $d % znorder(2, $q) == 0) {
  43. #~ push @{$common_divisors{$d}}, $q;
  44. #~ }
  45. #if ((($q % 24 == 1) or ($q % 24 == 13)) and is_prime($q)) {
  46. if (is_prime($q)) {
  47. my $z = znorder(2, $q);
  48. 2*$z < $limit or next;
  49. foreach my $d(divisors($q-1)) {
  50. if ($d % $z == 0 and exists $common_divisors{$d}) {
  51. push @{$common_divisors{$d}}, $q;
  52. }
  53. }
  54. }
  55. }
  56. }
  57. #}
  58. # }
  59. push @{$common_divisors{$d}}, $p;
  60. #}
  61. }
  62. # }
  63. }
  64. # }
  65. # }
  66. } 3, $limit;
  67. warn ":: Creating combinations...\n";
  68. #foreach my $arr (values %common_divisors) {
  69. while (my ($key, $arr) = each %common_divisors) {
  70. my $nf = 7; # minimum number of prime factors
  71. $arr = [uniq(@$arr)];
  72. #next if @$arr < $nf;
  73. my $l = scalar(@$arr);
  74. foreach my $k ($nf .. $l) {
  75. forcomb {
  76. my $n = Math::Prime::Util::GMP::vecprod(@{$arr}[@_]);
  77. $callback->($n);
  78. } $l, $k;
  79. }
  80. }
  81. }
  82. open my $fh, '>', 'super_poulet_numbers.txt';
  83. #$fh->autoflush(1);
  84. super_poulet_pseudoprimes(
  85. 1e8, # limit of the largest prime factor
  86. sub ($n) {
  87. if ($n > ~0) { # report only numbers greater than 2^64
  88. #warn "$n\n";
  89. say $fh $n;
  90. }
  91. }
  92. );
  93. close $fh;