smooth_generate.pl 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. #!/usr/bin/perl
  2. # Smallest number m such that the GCD of the x's that satisfy sigma(x)=m is n.
  3. # https://oeis.org/A241625
  4. # Known terms:
  5. # 1, 3, 4, 7, 6, 6187272, 8, 15, 13, 196602, 8105688, 28, 14
  6. # Upper-bounds for a(144):
  7. # a(144) <= {5334186182, 6653667020, 15812165226, 26999284026, 28752564542, 31717503246, 51526204158, 68240139110, 71641633206, 73884376566, 320692161764, 404350986572, 724592550812, 921030858722, 1138698021812, 7340065485194, 10562405788532, 405101345685452, 1058995989058904, 1293672253540082, 1991013491138282, 2643933035123354, 15645437418062582}
  8. # Other upper-bounds:
  9. # a(127) <= {4096, 1000153088, 1006583808}
  10. # Lower-bound for a(13):
  11. # a(13) > 1005756000
  12. # Upper-bounds for larger terms:
  13. # a(1444) <= 2667
  14. # a(4096) <= 8191
  15. # a(36100) <= 82677
  16. # a(94633984) <= 199753347
  17. use 5.014;
  18. use Math::GMPz;
  19. use Math::AnyNum qw(is_smooth);
  20. use ntheory qw(:all);
  21. use Memoize qw(memoize);
  22. use List::Util qw(uniq);
  23. use experimental qw(signatures);
  24. memoize('max_power');
  25. my @smooth_primes;
  26. sub is_smooth_for_e {
  27. my ($p, $e) = @_;
  28. is_smooth(Math::GMPz->new($p)**($e - 1), 7)
  29. and is_smooth(Math::GMPz->new($p)**($e + 1) - 1, 7);
  30. }
  31. sub p_is_smooth {
  32. my ($p) = @_;
  33. vecany {
  34. is_smooth_for_e($p, $_);
  35. }
  36. 1 .. 20;
  37. }
  38. sub max_power {
  39. my ($p) = @_;
  40. for (my $e = 20 ; $e >= 1 ; --$e) {
  41. if (is_smooth_for_e($p, $e)) {
  42. return $e;
  43. }
  44. }
  45. }
  46. forprimes {
  47. if ($_ == 2) {
  48. push @smooth_primes, $_;
  49. }
  50. else {
  51. if (p_is_smooth($_)) {
  52. push @smooth_primes, $_;
  53. }
  54. }
  55. } 4801;
  56. say "@smooth_primes";
  57. push @smooth_primes, (2, 13, 23, 29, 31, 41, 83, 127, 269, 1153);
  58. push @smooth_primes, (2, 3, 7, 11, 13, 31, 71, 151, 1009, 2833);
  59. @smooth_primes = uniq(@smooth_primes);
  60. @smooth_primes = sort { $a <=> $b } @smooth_primes;
  61. foreach my $p (@smooth_primes) {
  62. say "a($p) = ", max_power($p);
  63. }
  64. sub check_valuation ($n, $p) {
  65. $n % ($p * $p) != 0;
  66. }
  67. sub hamming_numbers ($limit, $primes) {
  68. my @h = (1);
  69. foreach my $p (@$primes) {
  70. say "Prime: $p";
  71. foreach my $n (@h) {
  72. if ($n * $p <= $limit and check_valuation($n, $p)) {
  73. push @h, $n * $p;
  74. }
  75. }
  76. }
  77. return \@h;
  78. }
  79. sub isok {
  80. my ($n) = @_;
  81. my $t = Math::GMPz->new(divisor_sum($n)) * Math::GMPz->new(euler_phi($n));
  82. is_power($t);
  83. }
  84. #use 5.016;
  85. #use Math::AnyNum qw(:overload);
  86. #die join ' ', inverse_sigma(19594645850);
  87. my $h = hamming_numbers(1e12, \@smooth_primes);
  88. say "Found: ", scalar(@$h), " terms";
  89. my %table;
  90. use utf8;
  91. use 5.020;
  92. use strict;
  93. use warnings;
  94. use integer;
  95. use ntheory qw(:all);
  96. use experimental qw(signatures);
  97. use List::Util qw(uniq);
  98. binmode(STDOUT, ':utf8');
  99. sub dynamicPreimage ($N, $L) {
  100. my %r = (1 => [1]);
  101. foreach my $l (@$L) {
  102. my %t;
  103. foreach my $pair (@$l) {
  104. my ($x, $y) = @$pair;
  105. foreach my $d (divisors(divint($N, $x))) {
  106. if (exists $r{$d}) {
  107. push @{$t{mulint($x, $d)}}, map { mulint($_, $y) } @{$r{$d}};
  108. }
  109. }
  110. }
  111. while (my ($k, $v) = each %t) {
  112. push @{$r{$k}}, @$v;
  113. }
  114. }
  115. return if not exists $r{$N};
  116. sort { $a <=> $b } @{$r{$N}};
  117. }
  118. sub cook_sigma ($N, $k) {
  119. my %L;
  120. foreach my $d (divisors($N)) {
  121. next if ($d == 1);
  122. foreach my $p (map { $_->[0] } factor_exp(subint($d, 1))) {
  123. my $q = addint(mulint($d, subint(powint($p, $k), 1)), 1);
  124. my $t = valuation($q, $p);
  125. next if ($t <= $k or ($t % $k) or $q != powint($p, $t));
  126. push @{$L{$p}}, [$d, powint($p, subint(divint($t, $k), 1))];
  127. }
  128. }
  129. [values %L];
  130. }
  131. sub inverse_sigma ($N, $k = 1) {
  132. ($N == 1) ? (1) : dynamicPreimage($N, cook_sigma($N, $k));
  133. }
  134. my %easy;
  135. @easy{
  136. 1, 2, 3, 4, 5, 7, 8, 9, 12, 13, 16, 25, 31, 80, 97, 18, 19, 22, 27, 29, 32, 36,
  137. 37, 43, 45, 49, 50, 61, 64, 67, 72, 73, 81, 91, 98, 100, 101, 106, 109, 121, 128, 129, 133, 134,
  138. 137, 146, 148, 149, 152, 157, 162, 163, 169, 171, 173, 192, 193, 197, 199, 200, 202, 211, 217, 218, 219
  139. } = ();
  140. my $count = 0;
  141. @$h = sort { $a <=> $b } @$h;
  142. #~ foreach my $n(@$h) {
  143. #~ if ($n == 5334186182) {
  144. #~ say "OK";
  145. #~ last;
  146. #~ }
  147. #~ }
  148. #~ say gcd(inverse_sigma(5334186182));
  149. #~ exit;
  150. foreach my $k (@$h) {
  151. say "Testing: $k" if (++$count % 1000 == 0);
  152. $k > 1e9 or next;
  153. my $t = gcd(inverse_sigma($k));
  154. if ($t >= 14 and $t <= 200) {
  155. say "\na($t) = $k\n" if not exists $easy{$t};
  156. if ($t == 14 or $t == 15) {
  157. say "Found: a($t) = $k";
  158. }
  159. }
  160. }