recursive_generation.pl 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #!/usr/bin/perl
  2. # Poulet numbers (Fermat pseudoprimes to base 2) k that have an abundancy index sigma(k)/k that is larger than the abundancy index of all smaller Poulet numbers.
  3. # https://oeis.org/A328691
  4. # Known terms:
  5. # 341, 561, 645, 18705, 2113665, 2882265, 81722145, 9234602385, 19154790699045, 43913624518905, 56123513337585, 162522591775545, 221776809518265, 3274782926266545, 4788772759754985
  6. use 5.014;
  7. use strict;
  8. use warnings;
  9. use experimental qw(signatures);
  10. use ntheory qw(forsquarefree forprimes divisor_sum);
  11. use Math::AnyNum;
  12. use Math::Prime::Util::GMP qw(gcd mulint is_pseudoprime divisors);
  13. my $rad = "903653840347639568725149973748479285201766630927341485";
  14. my @divisors = divisors($rad);
  15. my @squarefree;
  16. #forsquarefree {
  17. forprimes {
  18. #if (gcd($rad, $_) == 1 and $_ > 1) {
  19. push @squarefree, $_;
  20. #}
  21. } 1e8;
  22. my %seen;
  23. sub abundancy ($n) {
  24. (Math::AnyNum->new(divisor_sum($n)) / $n)->float;
  25. }
  26. sub generate ($root, $limit = 1.94) {
  27. my $abundancy = abundancy($root);
  28. $abundancy > $limit or return;
  29. return if $seen{$root}++;
  30. my @new;
  31. foreach my $s (@squarefree) {
  32. my $psp = mulint($s, $root);
  33. if (is_pseudoprime($psp, 2)) {
  34. say $psp, "\t-> ", abundancy($psp);
  35. push @new, $psp;
  36. }
  37. }
  38. if (@new) {
  39. say "# Found: ", scalar(@new), " new pseudoprimes";
  40. }
  41. foreach my $n(grep { abundancy($_) > $abundancy } @new) {
  42. generate($n, $abundancy);
  43. }
  44. }
  45. foreach my $d (@divisors) {
  46. if (is_pseudoprime($d, 2)) {
  47. say "# Divisor $d";
  48. generate($d);
  49. }
  50. }