lucas-carmichael.pl 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #!/usr/bin/perl
  2. # Generate Lucas-Carmichael numbers from a given Lucas-Carmichael number.
  3. use 5.020;
  4. use warnings;
  5. use ntheory qw(:all);
  6. use Math::GMPz;
  7. use Math::AnyNum qw(is_smooth);
  8. use experimental qw(signatures);
  9. use Math::Prime::Util::GMP qw(mulint divint gcd);
  10. sub check_valuation ($n, $p) {
  11. ($n % $p) != 0;
  12. }
  13. sub smooth_numbers ($limit, $primes) {
  14. my $k = 0;
  15. my $total = scalar(@$primes);
  16. my @h = (1);
  17. foreach my $p (@$primes) {
  18. say "[", ++$k, " out of $total] Prime: $p";
  19. foreach my $n (@h) {
  20. if ($n * $p <= $limit and check_valuation($n, $p)) {
  21. push @h, $n * $p;
  22. }
  23. }
  24. }
  25. return \@h;
  26. }
  27. #my $m = "120781417471";
  28. #my $m = "46852073639840281125599";
  29. my $m = "199195047359";
  30. my @factors = factor($m);
  31. my %factor_table;
  32. @factor_table{@factors} = ();
  33. sub is_lucas_carmichael ($n) {
  34. my $t = $n+1;
  35. return if not vecall { Math::GMPz::Rmpz_divisible_ui_p($t, $_+1) } @factors;
  36. vecall { Math::GMPz::Rmpz_divisible_ui_p($t, $_+1) } factor(divint($n, $m));
  37. }
  38. my $B_smooth = 11;
  39. my $t = Math::GMPz::Rmpz_init();
  40. my @primes = grep { is_smooth($_+1, $B_smooth) }grep{not exists $factor_table{$_}} @{primes($factors[-1])};
  41. my $max_primes = 100;
  42. if (@primes > $max_primes) {
  43. $#primes = $max_primes;
  44. }
  45. do {
  46. my $p = next_prime($factors[-1]);
  47. while (@primes < $max_primes) {
  48. if (is_smooth($p+1, $B_smooth)) {
  49. push @primes, $p;
  50. }
  51. $p = next_prime($p);
  52. }
  53. };
  54. my $terms = smooth_numbers(1e10, \@primes);
  55. foreach my $n (@$terms) {
  56. if (gcd($m, $n) == 1) {
  57. Math::GMPz::Rmpz_set_str($t, mulint($m, $n), 10);
  58. if (is_lucas_carmichael($t)) {
  59. say $t;
  60. }
  61. }
  62. }