generate_abundant_carmichael_numbers.pl 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. #!/usr/bin/perl
  2. # Erdos construction method for Carmichael numbers:
  3. # 1. Choose an even integer L with many prime factors.
  4. # 2. Let P be the set of primes d+1, where d|L and d+1 does not divide L.
  5. # 3. Find a subset S of P such that prod(S) == 1 (mod L). Then prod(S) is a Carmichael number.
  6. # Alternatively:
  7. # 3. Find a subset S of P such that prod(S) == prod(P) (mod L). Then prod(P) / prod(S) is a Carmichael number.
  8. use 5.020;
  9. use warnings;
  10. use ntheory qw(:all);
  11. use List::Util qw(shuffle);
  12. use experimental qw(signatures);
  13. # Modular product of a list of integers
  14. sub vecprodmod ($arr, $mod) {
  15. #~ if ($mod > ~0) {
  16. #~ my $prod = Math::GMPz->new(1);
  17. #~ foreach my $k(@$arr) {
  18. #~ $prod = ($prod * $k) % $mod;
  19. #~ }
  20. #~ return $prod;
  21. #~ }
  22. if ($mod < ~0) {
  23. my $prod = 1;
  24. foreach my $k(@$arr) {
  25. $prod = mulmod($prod, $k, $mod);
  26. }
  27. return $prod;
  28. }
  29. my $prod = 1;
  30. foreach my $k (@$arr) {
  31. $prod = Math::Prime::Util::GMP::mulmod($prod, $k, $mod);
  32. }
  33. Math::GMPz->new($prod);
  34. }
  35. # Primes p such that p-1 divides L and p does not divide L
  36. sub lambda_primes ($L) {
  37. #grep { ($L % $_) != 0 } grep { $_ > 2 and is_prime($_) } map { $_ + 1 } divisors($L);
  38. grep { ($_ > 2) and (($L % $_) != 0) and is_prime($_) } map { ($_ >= ~0) ? (Math::GMPz->new($_)+1) : ($_ + 1) } divisors($L);
  39. }
  40. #my @prefix = (3, 5, 17, 23, 29, 53, 83, 89);
  41. #my @prefix = (3,5,17,23, 29);
  42. #my @prefix = (3, 5, 17, 23, 29, 53, 83, 89);
  43. #my @prefix = (3, 5, 17, 23, 29, 53, 83, 89, 113, 353, 617, 2003, 2549);
  44. #my @prefix = (3, 5, 17, 23, 29, 53, 83, 89, 113, 353, 617);
  45. #my @prefix = (3, 5, 17, 23, 29, 53, 83, 89, 113, 419, 449, 617);
  46. #my @prefix = (3, 5, 17, 23, 29, 53, 83, 89, 113, 257, 353, 449, 617, 1409, 2003);
  47. #my @prefix = (3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 1409, 2003);
  48. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 257, 353, 617, 1409, 2003, 2549, 3137, 9857, 10193, 16073, 68993, 202049, 275969, 1500929, 18386369]
  49. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 2003, 2297, 2549, 3137, 9857, 10193, 68993, 88397, 93809, 5850209, 8044037, 18386369]
  50. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 2003, 2549, 3137, 4019, 4289, 10193, 16073, 21977, 38459, 50513, 52529, 76649, 93809, 97553]
  51. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 1409, 2003, 2549, 8009, 9857, 23297, 50513, 68993, 275969, 375233, 1500929, 3232769, 18386369]
  52. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 1409, 2003, 2297, 2549, 3329, 8009, 10193, 16073, 23297, 50177, 93809, 202049, 275969, 656657, 18386369]
  53. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 257, 353, 449, 617, 1409, 2003, 2297, 2549, 3137, 3329, 4019, 7547, 9857, 10193, 16073, 17837, 23297, 68993, 88397, 93809, 202049, 896897, 1500929, 2475089, 8044037, 18386369]
  54. foreach my $n(
  55. #qw(327976184723917106922696038500316850197097366397296955613721508063986316871814680735 685142249888262836361512024427161900061736398403953340277064230345667415945220868055415 1447705574013899373231874907614593094830449009827553408005436718720395249892251694201091895 3154550445776286734272255423692198353635548392414238876043846610091741249515216441664179239205 7498366409610233567365151142116355486591698528768645808356223392188068950097669481835754051590285 19443264100119335640177836911507709776732274285097098581067687255943662787603256966400110255773609005 6752147266492648336087178462400067734188627847011899231029509812418215 8622492059311111925183326896484886496558877760634195318024684030458060555 11183372200926512166962774984740897786036864455542551327478015187504104539835 15757371431105455643250549953499924980525942017859454820416523399193283296627515 22895460689396227049643049082435390996704193751949787854065208499027840629999779295 4065021504672018226118572207226948264489296099895 2126006246943465532260013264379693942327901860245085 1226705604486379612114027653547083404723199373361414045 837839927864197275073880887372657965425945172005845792735 8400431334513514794031775534168508142396705 3334971239801865373230614887064897732531491885 1444042546834207706608856246099100718186135986205 11304017840824088923079122979486080913570205802842055 8692789719593724381847845571224796222535488262385540295 8075601649502569950736648535667835690735468595756166934055 9020447042494370634972836414340972466551518421459638465339435 13972672468823780113572923605814166350688302034840979982810784815 21895177758646863437968771290310798671528569288595815633064499805105 45739026337813297721916763225459258424823181243876658857471740092864345 108721665604982208684996146186916657275804701816694818104210326200738548065 207093460403925930428246384004848306979999376211770028014102314959732822821308183615 14116844787629511288659115050445171405 6338463309645650568607942657649881960845 )
  56. #qw( 269616807542440095880838902934479765646815 39623553877269279114765582013213715065835439560755)
  57. #qw(80457526688110964090941908021307082343637031298345387811989511961940980765)
  58. #qw(156400339552952614158261462316373572492517490659424507963838717745)
  59. #qw(30300520893268092108675921598650019435254761657479255573181729185)
  60. #qw(23727894199896704861923196240133139730035052198495893166156405)
  61. #qw(5560414251522943074360489383944833466511209118626077678018703909135127547157897173895)
  62. #qw(14807987984119898011183681250338047627675234576733585022035)
  63. #qw(1469693990779095715245182961386962460712186859726612101336192430649765)
  64. #qw(10094456962219244277998564908104312836457170747058383045)
  65. #qw(48976162706891785856850267556951183909509591565)
  66. #qw(232256510885289043333840440634089959783515)
  67. #qw(76901951875930663768872450745768943476147523769184184245)
  68. #qw(93426807299183714704340654128147124952637393355)
  69. qw(100567069213330155763552910794560952586261995)
  70. #qw(2291345950693302094766820752641350945890207963412715)
  71. #qw(327976184723917106922696038500316850197097366397296955613721508063986316871814680735 685142249888262836361512024427161900061736398403953340277064230345667415945220868055415 1447705574013899373231874907614593094830449009827553408005436718720395249892251694201091895 3154550445776286734272255423692198353635548392414238876043846610091741249515216441664179239205 7498366409610233567365151142116355486591698528768645808356223392188068950097669481835754051590285 19443264100119335640177836911507709776732274285097098581067687255943662787603256966400110255773609005 6752147266492648336087178462400067734188627847011899231029509812418215 8622492059311111925183326896484886496558877760634195318024684030458060555 11183372200926512166962774984740897786036864455542551327478015187504104539835 15757371431105455643250549953499924980525942017859454820416523399193283296627515 22895460689396227049643049082435390996704193751949787854065208499027840629999779295 80175683972122511383731338517508443634187270777707283918484112701538301509380205 125635296784315975338307007456935731174771453308667313900264604603310518465198781235 224007734166435384028201394295716408684617501249353820684171790007702654423449426942005 467952156673683517234912712683751577742165960109900131409234869326090845090585852881848445 988782907051493271917370561900767083769196673712218977667713278886029955676407907139345764285 2154557954465203839507950454381771475533079552018925152337947234692659273418892829656634420377015 5121384257763789526510398230065470797342130095148985087107300576864451092916708256093820017236164655 13279749380381506242241462610559765777508143336721318330869230395809521683933024508051275304693374950415 4065021504672018226118572207226948264489296099895 2126006246943465532260013264379693942327901860245085 1226705604486379612114027653547083404723199373361414045 837839927864197275073880887372657965425945172005845792735 19560340012826425693128516437578862635 8400431334513514794031775534168508142396705 3334971239801865373230614887064897732531491885 1444042546834207706608856246099100718186135986205 11304017840824088923079122979486080913570205802842055 8692789719593724381847845571224796222535488262385540295 8075601649502569950736648535667835690735468595756166934055 9020447042494370634972836414340972466551518421459638465339435 13972672468823780113572923605814166350688302034840979982810784815 21895177758646863437968771290310798671528569288595815633064499805105 45739026337813297721916763225459258424823181243876658857471740092864345 108721665604982208684996146186916657275804701816694818104210326200738548065 17277031840122951876810012573270045985 99436691737018840272248469415851811397274754265692619259832323874449185818279122553922438597548102645740113148322901071530942568237363765081022282605920356808140142566166169841228255378791958207751846269805134897319182266879091065192147432933981465795852869698389629543929 895029662324906581290508473212082154386870063145499265957750747193917121550330382107855869816530471914306758448054432544850014056704511249494281565735889131630069423238061694740895526664506415827974368274516019210769959584178698677794519043838767173628471680155205055524904929 8306770296037457980957209139881334474864541056053378687353884684706744805108616276343010327767219309836681025156393188448752980460274568906556427211594787030658674317072450588890251382973284045299430111955783174295155994900762502428610931245867598138445845663520458120326642646049 78058720471863992647054894287464900060302092303733599525064454382189280933605667148795268050028559854535291593394626791852931757385200124014910746507356213727099562557529818183801692245799950173678744762048494488851580884082465235321656920917417819706975611700101744956709460944922453 749441775250366193404374040053950505478960388208146289040143826523399286243548010295583368548324203163393334588181811828579997802655306390667158077217127007993882900114843784382680047251925321617489628460427595587464028068075748724323228097728128487006672847932676853329367534532200471253 207093460403925930428246384004848306979999376211770028014102314959732822821308183615 14116844787629511288659115050445171405 6338463309645650568607942657649881960845 83562900542610185478464992069940404422726948660826302385114906951342076455803610529344640789 50221303226108721472557460234034183058058896145156607733454059077756587949937969928136129114189 32191855367935690463909332010015911340215752429045385557144051868841972875910238723935258762195149 73447150516193077029324563940188527242280274750433560293457441337357999076671648487217809)
  72. #qw(1568442344968558041435703706985298315 622671610952517542449974371673163431055 269616807542440095880838902934479765646815)
  73. #qw(80457526688110964090941908021307082343637031298345387811989511961940980765)
  74. #qw(183946261763273755985808210039437380929387193716936037921324457691523453096923545)
  75. #qw(80457526688110964090941908021307082343637031298345387811989511961940980765)
  76. #qw(68671670497867034860945549416314930790009427315 39623553877269279114765582013213715065835439560755 28806323668774765916434578123606370852862364560668885 22152062901287794989738190577053299185851158347154372565 20579266435296361545466779046082514943655726104506412112885 23727894199896704861923196240133139730035052198495893166156405 30300520893268092108675921598650019435254761657479255573181729185 39299775598568715464952670313449075207525425869750594478416702752945 55373383818383320090118312471649746967403325050478587620089134178899505 80457526688110964090941908021307082343637031298345387811989511961940980765 117387531437953896608684243803087033139366428664285920817692697952471890936135 183946261763273755985808210039437380929387193716936037921324457691523453096923545)
  77. #qw(100567069213330155763552910794560952586261995)
  78. #qw(39623553877269279114765582013213715065835439560755)
  79. #qw(23727894199896704861923196240133139730035052198495893166156405 30300520893268092108675921598650019435254761657479255573181729185 39299775598568715464952670313449075207525425869750594478416702752945 55373383818383320090118312471649746967403325050478587620089134178899505 80457526688110964090941908021307082343637031298345387811989511961940980765)
  80. ) {
  81. my @prefix = factor($n);
  82. #my @prefix = (3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 257, 353, 449, 617, 1409, 2003, 2297, 2549, 3137, 3329, 4019);
  83. #my @prefix = (5, 7, 13, 17, 19, 23, 37, 59, 67, 73, 89, 97, 109, 163, 193, 199, 233, 257, 349, 353, 397, 433, 487, 523, 577, 727, 769, 929, 1153, 1277, 1297, 1409, 1453, 1459, 1567, 1783, 2089, 2113, 2179, 2377, 2593);
  84. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 2003, 2297, 2549, 3137, 9857, 10193, 68993, 88397, 93809, 5850209, 8044037, 18386369]
  85. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 2003, 2549, 3137, 4019, 4289, 10193, 16073, 21977, 38459, 50513, 52529, 76649, 93809, 97553]
  86. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 1409, 2003, 2549, 8009, 9857, 23297, 50513, 68993, 275969, 375233, 1500929, 3232769, 18386369]
  87. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 197, 353, 449, 617, 1409, 2003, 2297, 2549, 3329, 8009, 10193, 16073, 23297, 50177, 93809, 202049, 275969, 656657, 18386369]
  88. #~ [3, 5, 17, 23, 29, 53, 83, 89, 113, 257, 353, 449, 617, 1409, 2003, 2297, 2549, 3137, 3329, 4019, 7547, 9857, 10193, 16073, 17837, 23297, 68993, 88397, 93809, 202049, 896897, 1500929, 2475089, 8044037, 18386369]
  89. #my @prefix = (3, 5, 17, 23, 29);
  90. my $prefix_prod = Math::GMPz->new(vecprod(@prefix));
  91. my sub method_1 ($L) { # smallest numbers first
  92. (vecall { ($L % ($_-1)) == 0 } @prefix) or return;
  93. my @P = lambda_primes($L);
  94. #@P = grep{$_ < 1e5 } @P;
  95. #~ @P = grep {
  96. #~ (($prefix_prod % $_) == 0)
  97. #~ ? 1
  98. #~ : Math::Prime::Util::GMP::gcd(Math::Prime::Util::GMP::totient(Math::Prime::Util::GMP::mulint($prefix_prod, $_)), Math::Prime::Util::GMP::mulint($prefix_prod, $_)) eq '1'
  99. #~ } @P;
  100. #vecprodmod(@P, 3*5*17*23) == 0 or return;
  101. #vecprodmod(\@P, 3*5*17*23*29) == 0 or return;
  102. if (@prefix) {
  103. vecprodmod(\@P, $prefix_prod) == 0 or return;
  104. }
  105. #return if (vecprod(@P) < ~0);
  106. #@P = grep { $_ > $prefix[-1] } @P;
  107. @P = grep { gcd($prefix_prod, $_) == 1 } @P;
  108. say "# Testing: $L -- ", scalar(@P);
  109. my $n = scalar(@P);
  110. my @orig = @P;
  111. my $max = 1e6;
  112. my $max_k = scalar(@prefix)>>1;
  113. my $L_rem = invmod($prefix_prod, $L);
  114. foreach my $k (1 .. @P) {
  115. #next if (binomial($n, $k) > 1e6);
  116. next if ($k > $max_k);
  117. @P = @orig;
  118. my $count = 0;
  119. forcomb {
  120. if (vecprodmod([@P[@_]], $L) == $L_rem) {
  121. say vecprod(@P[@_], $prefix_prod);
  122. }
  123. lastfor if (++$count > $max);
  124. } $n, $k;
  125. next if (binomial($n, $k) < $max);
  126. @P = reverse(@P);
  127. $count = 0;
  128. forcomb {
  129. if (vecprodmod([@P[@_]], $L) == $L_rem) {
  130. say vecprod(@P[@_], $prefix_prod);
  131. }
  132. lastfor if (++$count > $max);
  133. } $n, $k;
  134. @P = shuffle(@P);
  135. $count = 0;
  136. forcomb {
  137. if (vecprodmod([@P[@_]], $L) == $L_rem) {
  138. say vecprod(@P[@_], $prefix_prod);
  139. }
  140. lastfor if (++$count > $max);
  141. } $n, $k;
  142. }
  143. my $B = vecprodmod([@P, $prefix_prod], $L);
  144. my $T = Math::GMPz->new(Math::Prime::Util::GMP::vecprod(@P));
  145. foreach my $k (1 .. @P) {
  146. #next if (binomial($n, $k) > 1e6);
  147. last if ($k > $max_k);
  148. @P = @orig;
  149. my $count = 0;
  150. forcomb {
  151. if (vecprodmod([@P[@_]], $L) == $B) {
  152. my $S = Math::GMPz->new(Math::Prime::Util::GMP::vecprod(@P[@_]));
  153. say vecprod($prefix_prod, $T / $S) if ($T != $S);
  154. }
  155. lastfor if (++$count > $max);
  156. } $n, $k;
  157. next if (binomial($n, $k) < $max);
  158. @P = reverse(@P);
  159. $count = 0;
  160. forcomb {
  161. if (vecprodmod([@P[@_]], $L) == $B) {
  162. my $S = Math::GMPz->new(Math::Prime::Util::GMP::vecprod(@P[@_]));
  163. say vecprod($prefix_prod, $T / $S) if ($T != $S);
  164. }
  165. lastfor if (++$count > $max);
  166. } $n, $k;
  167. @P = shuffle(@P);
  168. $count = 0;
  169. forcomb {
  170. if (vecprodmod([@P[@_]], $L) == $B) {
  171. my $S = Math::GMPz->new(Math::Prime::Util::GMP::vecprod(@P[@_]));
  172. say vecprod($prefix_prod, $T / $S) if ($T != $S);
  173. }
  174. lastfor if (++$count > $max);
  175. } $n, $k;
  176. }
  177. }
  178. use Math::GMPz;
  179. #my %seen;
  180. #my $count = 0;
  181. #method_1(205058304)
  182. method_1(carmichael_lambda($prefix_prod));
  183. }
  184. __END__
  185. while (<>) {
  186. chomp(my $n = $_);
  187. #$n > 1e5 or next;
  188. #$n *= 656656;
  189. #$n *= 78848;
  190. #$n *= 1232;
  191. #$n = lcm($n, 29586292736);
  192. #$n = lcm($n, 1232);
  193. #$n = lcm($n, 5789168, 147090944);
  194. #$n = lcm($n, 78848);
  195. #$n = lcm($n, 656656);
  196. #$n = lcm($n, 9193184);
  197. #$n = lcm($n, 10506496);
  198. #$n = lcm($n, 36772736);
  199. #~ next if ($n < 707981814540);
  200. #~ next if ($n > 44351949725003712);
  201. #next if ($n < 1e6);
  202. #next if ($n < 1e8);
  203. #next if ($n < 7813080); # for 2^64
  204. #next if ($n < ~0);
  205. #next if ($n < 17125441200);
  206. #next if (length($n) > 45);
  207. # if (++$count % 1000 == 0) {
  208. #say "Testing: $n";
  209. # $count = 0 ;
  210. # }
  211. #say "Testing: $n";
  212. if ($n > ~0) {
  213. $n = Math::GMPz->new($n);
  214. }
  215. next if $seen{$n}++;
  216. method_1($n);
  217. }