carmichael_with_gcd_phi_lambda_cached.pl 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #!/usr/bin/perl
  2. # Carmichael numbers n such that gcd(n-1, phi(n))**2 / lambda(n)**2 >= n-1.
  3. # Problem from:
  4. # https://math.stackexchange.com/questions/4157474/carmichael-number-n-such-that-frac-gcdn-1-phin2-lambdan2-geq-n
  5. use 5.020;
  6. use strict;
  7. use warnings;
  8. use Storable;
  9. use Math::GMPz;
  10. use ntheory qw(:all);
  11. use POSIX qw(ULONG_MAX);
  12. #use Math::Sidef qw(is_fibonacci);
  13. #use Math::Prime::Util::GMP;
  14. use experimental qw(signatures);
  15. #use List::Util qw(uniq);
  16. my $carmichael_file = "cache/factors-carmichael.storable";
  17. my $carmichael = retrieve($carmichael_file);
  18. sub my_euler_phi ($factors) { # assumes n is squarefree
  19. state $t = Math::GMPz::Rmpz_init();
  20. state $u = Math::GMPz::Rmpz_init();
  21. Math::GMPz::Rmpz_set_ui($t, 1);
  22. foreach my $p (@$factors) {
  23. if ($p < ULONG_MAX) {
  24. Math::GMPz::Rmpz_mul_ui($t, $t, $p - 1);
  25. }
  26. else {
  27. Math::GMPz::Rmpz_set_str($u, "$p", 10);
  28. Math::GMPz::Rmpz_sub_ui($u, $u, 1);
  29. Math::GMPz::Rmpz_mul($t, $t, $u);
  30. }
  31. }
  32. return $t;
  33. }
  34. sub my_carmichael_lambda ($factors) { # assumes n is squarefree
  35. state $t = Math::GMPz::Rmpz_init();
  36. state $u = Math::GMPz::Rmpz_init();
  37. Math::GMPz::Rmpz_set_ui($t, 1);
  38. foreach my $p (@$factors) {
  39. if ($p < ULONG_MAX) {
  40. Math::GMPz::Rmpz_lcm_ui($t, $t, $p - 1);
  41. }
  42. else {
  43. Math::GMPz::Rmpz_set_str($u, "$p", 10);
  44. Math::GMPz::Rmpz_sub_ui($u, $u, 1);
  45. Math::GMPz::Rmpz_lcm($t, $t, $u);
  46. }
  47. }
  48. return $t;
  49. }
  50. my $u = Math::GMPz::Rmpz_init_set_ui(0);
  51. my $t = Math::GMPz::Rmpz_init_set_ui(0);
  52. while(my($key, $value) = each %$carmichael) {
  53. my @factors = split(' ', $value);
  54. my $phi = my_euler_phi(\@factors);
  55. my $lambda = my_euler_phi(\@factors);
  56. Math::GMPz::Rmpz_set_str($u, $key, 10);
  57. Math::GMPz::Rmpz_sub_ui($u, $u, 1);
  58. Math::GMPz::Rmpz_gcd($t, $u, $phi);
  59. Math::GMPz::Rmpz_mul($t, $t, $t);
  60. Math::GMPz::Rmpz_mul($lambda, $lambda, $lambda);
  61. Math::GMPz::Rmpz_divexact($t, $t, $lambda);
  62. if (Math::GMPz::Rmpz_cmp($t, $u) >= 0) {
  63. say $key;
  64. }
  65. }
  66. __END__
  67. # No such number is known...