generate_fermat_superpseudoprimes.pl 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #!/usr/bin/perl
  2. # Author: Daniel "Trizen" Șuteu
  3. # Date: 28 January 2019
  4. # https://github.com/trizen
  5. # A new algorithm for generating Fermat overpseudoprimes to any given base.
  6. # See also:
  7. # https://oeis.org/A141232 -- Overpseudoprimes to base 2: composite k such that k = A137576((k-1)/2).
  8. # See also:
  9. # https://en.wikipedia.org/wiki/Fermat_pseudoprime
  10. # https://trizenx.blogspot.com/2020/08/pseudoprimes-construction-methods-and.html
  11. use 5.020;
  12. use warnings;
  13. use experimental qw(signatures);
  14. use Math::AnyNum qw(prod);
  15. use ntheory qw(:all);
  16. sub fermat_overpseudoprimes ($base, $prime_limit, $callback) {
  17. my %common_divisors;
  18. say ":: Sieving...";
  19. forprimes {
  20. my $p = $_;
  21. my $z = znorder($base, $p);
  22. foreach my $d(divisors($p-1)) {
  23. $d % $z == 0 or next;
  24. if ($p < 3e7 or exists($common_divisors{$d})) {
  25. push @{$common_divisors{$d}}, $p;
  26. }
  27. }
  28. } 3, $prime_limit;
  29. say ":: Done sieving...";
  30. foreach my $arr (values %common_divisors) {
  31. my $l = scalar(@$arr);
  32. foreach my $k (5 .. $l) {
  33. forcomb {
  34. my $n = prod(@{$arr}[@_]);
  35. $callback->($n);
  36. } $l, $k;
  37. }
  38. }
  39. }
  40. sub is_fibonacci_pseudoprime ($n) {
  41. (lucas_sequence($n, 1, -1, $n - kronecker($n, 5)))[0] == 0;
  42. }
  43. my $base = 2; # generate overpseudoprime to this base
  44. my $prime_limit = 1e9; # sieve primes up to this limit
  45. open my $fh, '>', 'file9.txt';
  46. fermat_overpseudoprimes(
  47. $base, # base
  48. $prime_limit, # prime limit
  49. sub ($n) {
  50. say $n;
  51. say $fh $n;
  52. }
  53. );