prog.pl 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #!/usr/bin/perl
  2. # Number of eleven-prime Carmichael numbers less than 10^n.
  3. # https://oeis.org/A299711
  4. # Known terms:
  5. # 1, 49, 576, 5804, 42764
  6. use 5.036;
  7. use Math::GMPz;
  8. use ntheory qw(:all);
  9. sub count_carmichael_numbers_in_range ($A, $B, $k) {
  10. $A = vecmax($A, pn_primorial($k + 1) >> 1);
  11. $A = Math::GMPz->new("$A");
  12. $B = Math::GMPz->new("$B");
  13. my $u = Math::GMPz::Rmpz_init();
  14. my $v = Math::GMPz::Rmpz_init();
  15. sub ($m, $L, $lo, $k) {
  16. Math::GMPz::Rmpz_tdiv_q($u, $B, $m);
  17. Math::GMPz::Rmpz_root($u, $u, $k);
  18. my $hi = Math::GMPz::Rmpz_get_ui($u);
  19. if ($lo > $hi) {
  20. return 0;
  21. }
  22. if ($k == 1) {
  23. Math::GMPz::Rmpz_cdiv_q($u, $A, $m);
  24. if (Math::GMPz::Rmpz_fits_ulong_p($u)) {
  25. $lo = vecmax($lo, Math::GMPz::Rmpz_get_ui($u));
  26. }
  27. elsif (Math::GMPz::Rmpz_cmp_ui($u, $lo) > 0) {
  28. if (Math::GMPz::Rmpz_cmp_ui($u, $hi) > 0) {
  29. return 0;
  30. }
  31. $lo = Math::GMPz::Rmpz_get_ui($u);
  32. }
  33. if ($lo > $hi) {
  34. return 0;
  35. }
  36. Math::GMPz::Rmpz_invert($v, $m, $L);
  37. if (Math::GMPz::Rmpz_fits_ulong_p($L)) {
  38. $L = Math::GMPz::Rmpz_get_ui($L);
  39. }
  40. my $t = Math::GMPz::Rmpz_get_ui($v);
  41. $t > $hi && return 0;
  42. $t += $L while ($t < $lo);
  43. my $count = 0;
  44. for (my $p = $t ; $p <= $hi ; $p += $L) {
  45. if (is_prime($p)) {
  46. Math::GMPz::Rmpz_mul_ui($v, $m, $p);
  47. Math::GMPz::Rmpz_sub_ui($u, $v, 1);
  48. if (Math::GMPz::Rmpz_divisible_ui_p($u, $p - 1)) {
  49. ++$count;
  50. }
  51. }
  52. }
  53. return $count;
  54. }
  55. my $count = 0;
  56. my $z = Math::GMPz::Rmpz_init();
  57. my $lcm = Math::GMPz::Rmpz_init();
  58. foreach my $p (@{primes($lo, $hi)}) {
  59. Math::GMPz::Rmpz_gcd_ui($Math::GMPz::NULL, $m, $p-1) == 1 or next;
  60. Math::GMPz::Rmpz_mul_ui($z, $m, $p);
  61. Math::GMPz::Rmpz_lcm_ui($lcm, $L, $p-1);
  62. $count += __SUB__->($z, $lcm, $p + 1, $k - 1);
  63. }
  64. return $count;
  65. }
  66. ->(Math::GMPz->new(1), Math::GMPz->new(1), 3, $k);
  67. }
  68. my $k = 11;
  69. my $total = 0;
  70. foreach my $n (17..100) {
  71. $total += count_carmichael_numbers_in_range(powint(10, $n-1), powint(10, $n), $k);
  72. say "a($n) = ", $total;
  73. }
  74. __END__
  75. a(17) = 1
  76. a(18) = 49
  77. a(19) = 576
  78. a(20) = 5804