abundant_carmichael_cached.pl 1.2 KB

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