lehmer_totient_weak_numbers_cached.pl 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. #!/usr/bin/perl
  2. # Composite numbers n such that phi(n) divides p*(n - 1) for some prime factor p of n-1.
  3. # https://oeis.org/A338998
  4. # Known terms:
  5. # 1729, 12801, 5079361, 34479361, 3069196417
  6. use 5.020;
  7. use strict;
  8. use warnings;
  9. use experimental qw(signatures);
  10. use Storable;
  11. use Math::GMPz;
  12. use ntheory qw(:all);
  13. use Math::Prime::Util::GMP;
  14. use experimental qw(signatures);
  15. use Math::Sidef qw(trial_factor);
  16. use List::Util qw(uniq);
  17. use POSIX qw(ULONG_MAX);
  18. my $carmichael_file = "cache/factors-carmichael.storable";
  19. my $carmichael = retrieve($carmichael_file);
  20. #~ sub my_euler_phi ($factors) { # assumes n is squarefree
  21. #~ Math::Prime::Util::GMP::vecprod(map { ($_ < ~0) ? ($_ - 1) : Math::Prime::Util::GMP::subint($_, 1) } @$factors);
  22. #~ }
  23. sub my_euler_phi ($factors) { # assumes n is squarefree
  24. state $t = Math::GMPz::Rmpz_init();
  25. state $u = Math::GMPz::Rmpz_init();
  26. Math::GMPz::Rmpz_set_ui($t, 1);
  27. foreach my $p (@$factors) {
  28. if ($p < ULONG_MAX) {
  29. Math::GMPz::Rmpz_mul_ui($t, $t, $p - 1);
  30. }
  31. else {
  32. Math::GMPz::Rmpz_set_str($u, $p, 10);
  33. Math::GMPz::Rmpz_sub_ui($u, $u, 1);
  34. Math::GMPz::Rmpz_mul($t, $t, $u);
  35. }
  36. }
  37. return $t;
  38. }
  39. sub is_smooth_over_prod ($n, $k) {
  40. state $g = Math::GMPz::Rmpz_init_nobless();
  41. state $t = Math::GMPz::Rmpz_init_nobless();
  42. Math::GMPz::Rmpz_set($t, $n);
  43. Math::GMPz::Rmpz_gcd($g, $t, $k);
  44. while (Math::GMPz::Rmpz_cmp_ui($g, 1) > 0) {
  45. Math::GMPz::Rmpz_remove($t, $t, $g);
  46. return 1 if Math::GMPz::Rmpz_cmp_ui($t, 1) == 0;
  47. Math::GMPz::Rmpz_gcd($g, $t, $g);
  48. }
  49. return 0;
  50. }
  51. my $t = Math::GMPz::Rmpz_init();
  52. my $nm1 = Math::GMPz::Rmpz_init();
  53. while (my ($key, $value) = each %$carmichael) {
  54. # length($key) <= 30 or next;
  55. Math::GMPz::Rmpz_set_str($nm1, $key, 10);
  56. Math::GMPz::Rmpz_sub_ui($nm1, $nm1, 1);
  57. my @factors = split(' ', $value);
  58. my $phi = my_euler_phi(\@factors);
  59. Math::GMPz::Rmpz_gcd($t, $phi, $nm1);
  60. Math::GMPz::Rmpz_divexact($t, $phi, $t);
  61. #~ if (Math::GMPz::Rmpz_divisible_p($nm1, $t)) {
  62. if (Math::GMPz::Rmpz_divisible_p($nm1, $t)) {
  63. if (is_prime(Math::GMPz::Rmpz_get_str($t, 10))) {
  64. say "\nFound term: $key\n";
  65. }
  66. else {
  67. say "$t -> ", $key;
  68. }
  69. }
  70. }
  71. __END__
  72. # No terms > 2^64 are known.
  73. # If we relax the problem such that k is allowed to be composite, then we have (k -> n):
  74. 256 -> 161053591977104597648385
  75. 4320 -> 1442607709754537310156481
  76. 276480 -> 121311396642375203328001
  77. 36664320 -> 18307378995828443136001
  78. 39243204 -> 522701579776994601985
  79. 164647296 -> 710498768604458891905
  80. 239368932 -> 166767515214109647553
  81. 239855616 -> 69331699150300274689
  82. 344198160 -> 26220447360756492481
  83. 470271360 -> 22577695684076482561
  84. 494534656 -> 9370403366634042163201
  85. 690069744 -> 26412091255782290298241
  86. 847888206 -> 508856401419300817312321
  87. 1008611352 -> 225751988643126523201
  88. 1022867120 -> 151320171400394261761
  89. 1270746144 -> 1973514672419436576001
  90. 1355878368 -> 25043558587894400823361
  91. 1713960000 -> 405475097425913520001
  92. 2595175200 -> 79919351614524024001
  93. 3936306240 -> 22695373452873769921
  94. 4414596480 -> 2819631734736201434649601
  95. 4766062840 -> 305022961592329915047961
  96. 5256049760 -> 1454162635820073015201
  97. 6723894240 -> 23152815997129790193601
  98. 9337407520 -> 588513459619254160321
  99. 12358835370 -> 271556534518852228430401
  100. 14172416640 -> 57199945443705577825921
  101. 14385833280 -> 8449460360571792219841
  102. 20042190000 -> 3976684712865158490001
  103. 22016352600 -> 43988320199517413227201
  104. 23021417472 -> 2484569421264140859210670081
  105. 35963136000 -> 3221275513469123100672001
  106. 42830346240 -> 38223250373318642652303361
  107. 47342232000 -> 2479639741736856792912001
  108. 100711683072 -> 172991335211656109051905
  109. 225735802880 -> 24454143142535092272994713601
  110. 299747952000 -> 3373971932766269202480001
  111. 521132748000 -> 24305672075484052148160001
  112. 638306611200 -> 244560890510134115626598401
  113. 648369446400 -> 21566311675749133571835648001
  114. 768266286228 -> 19674209294344913441970817
  115. 938064067200 -> 33803763411350231745638401
  116. 1050025132800 -> 4775814557195289074611201
  117. 1127001600000 -> 77755530778217753011200001
  118. 1231491998240 -> 1585372177726779981269921
  119. 1299266121600 -> 566296873170734780865792001
  120. 1712586456000 -> 18856002135543697675152001
  121. 3473510584320 -> 256551983459660482787450881
  122. 6546891384000 -> 60060884070685995775533024001
  123. 7062492272640 -> 169302315858010163156179353601
  124. 10390842000000 -> 224159025932793824796000001
  125. 11788391160000 -> 1836659845422904698410760001
  126. 14246648367828 -> 7429200724594400259443892735745
  127. 20751621203808 -> 6753985548147606751087157673985
  128. 28322297280000 -> 22584599278031754549573120001
  129. 43712316942336 -> 5423553691041141223181881345
  130. 53989739274240 -> 26468027537347458252574433281
  131. 144645490376640 -> 22031534549990632963014227521
  132. 194461205316000 -> 16267018441058472048178342860001
  133. 231593852160000 -> 280329366963716628966650880001
  134. 1004376125491200 -> 851213068769837939865599760537601