super_poulet_pseudoprimes_from_prime_file.pl 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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 ($primes, $callback) {
  11. my %common_divisors;
  12. warn ":: Sieving...\n";
  13. my %seen;
  14. foreach my $p (@$primes) {
  15. modint($p, 8) == 3 or next;
  16. kronecker(5, $p) == -1 or next;
  17. next if $seen{$p}++;
  18. $p >= 3 or next;
  19. #$p < ~0 or next; # ignore too large primes
  20. my $z = znorder(2, $p);
  21. foreach my $d (divisors(subint($p, 1))) {
  22. if (modint($d, $z) == 0) {
  23. push @{$common_divisors{$d}}, $p;
  24. }
  25. }
  26. #~ foreach my $d (divisors(subint($p, kronecker(5, $p)))) {
  27. #~ if (lucasumod(1, -1, $d, $p) == 0) {
  28. #~ #if ($d > 1 and lucasvmod(1, -1, $d, $p) == 1) {
  29. #~ push @{$common_divisors{$d}}, $p;
  30. #~ }
  31. #~ }
  32. }
  33. warn ":: Creating combinations...\n";
  34. #foreach my $arr (values %common_divisors) {
  35. while (my ($key, $arr) = each %common_divisors) {
  36. my $nf = 3; # minimum number of prime factors
  37. $arr = [uniq(@$arr)];
  38. my $l = scalar(@$arr);
  39. say "$l -- $nf -- @$arr" if ($l > 1);
  40. #foreach my $k ($nf .. $l) {
  41. for (my $k = $nf ; $k <= $l ; $k += 2) {
  42. forcomb {
  43. $callback->(Math::Prime::Util::GMP::vecprod(@{$arr}[@_]));
  44. }
  45. $l, $k;
  46. }
  47. }
  48. }
  49. my @primes;
  50. while (<>) {
  51. next if /^#/;
  52. /\d/ or next;
  53. my $p = (split(' ', $_))[-1];
  54. push @primes, $p;
  55. }
  56. open my $fh, '>', 'super_poulet_numbers.txt';
  57. #$fh->autoflush(1);
  58. super_poulet_pseudoprimes(
  59. \@primes,
  60. sub ($n) {
  61. if ($n > ~0) { # report only numbers greater than 2^64
  62. warn "$n\n";
  63. say $fh $n;
  64. }
  65. }
  66. );
  67. close $fh;