abundant_fermat_pseudoprimes_cached.pl 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #!/usr/bin/perl
  2. # a(n) = smallest pseudoprime to base 2 with n prime factors.
  3. # https://oeis.org/A007011
  4. # Several abundant Fermat pseudoprimes to base 2:
  5. # 898943937249247967890084629421065
  6. # 222042825169546323981793629414604065
  7. # 2596282479202818734176082185090403265
  8. # 12796625128232187655293894634808130945
  9. # 3470207934739664512679701940114447720865
  10. use 5.020;
  11. use strict;
  12. use warnings;
  13. use Storable;
  14. use Math::GMPz;
  15. use ntheory qw(:all);
  16. use Math::Prime::Util::GMP;
  17. use experimental qw(signatures);
  18. use POSIX qw(ULONG_MAX);
  19. my $storable_file = "cache/factors-fermat.storable";
  20. my $fermat = retrieve($storable_file);
  21. sub my_sigma ($factors) { # assumes n is squarefree
  22. state $t = Math::GMPz::Rmpz_init();
  23. state $u = Math::GMPz::Rmpz_init();
  24. Math::GMPz::Rmpz_set_ui($t, 1);
  25. foreach my $p (@$factors) {
  26. if ($p < ULONG_MAX) {
  27. Math::GMPz::Rmpz_mul_ui($t, $t, $p + 1);
  28. }
  29. else {
  30. Math::GMPz::Rmpz_set_str($u, $p, 10);
  31. Math::GMPz::Rmpz_add_ui($u, $u, 1);
  32. Math::GMPz::Rmpz_mul($t, $t, $u);
  33. }
  34. }
  35. return $t;
  36. }
  37. my $t = Math::GMPz::Rmpz_init();
  38. while (my ($key, $value) = each %$fermat) {
  39. Math::Prime::Util::GMP::modint($key, 5) == 0
  40. or Math::Prime::Util::GMP::modint($key, 3) == 0
  41. or next;
  42. my @factors = split(' ', $value);
  43. Math::GMPz::Rmpz_set_str($t, $key, 10);
  44. Math::GMPz::Rmpz_mul_2exp($t, $t, 1);
  45. if (my_sigma(\@factors) >= $t) {
  46. say $key;
  47. }
  48. }