smooth_generate.pl 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #!/usr/bin/perl
  2. # Numbers that set a new record for number of Fibonacci divisors.
  3. # https://oeis.org/A129655
  4. #~ a(15) <= 523410559111440
  5. #~ a(16) <= 24076885719126240
  6. #~ a(17) <= 1131613628798933280
  7. #~ a(18) <= 100713612963105061920
  8. # New upper-bounds:
  9. # a(19) <= 32329069761156724876320
  10. # a(20) <= 8946490953125585755415520
  11. # a(21) <= 2871823595953313027488381920
  12. # In general:
  13. # a(n) <= A035105(n+1).
  14. use 5.020;
  15. use warnings;
  16. use experimental qw(signatures);
  17. use Math::GMPz;
  18. use ntheory qw(:all);
  19. # Exponents:
  20. # [[2, 3]], [[2, 4], [3, 2]], [[2, 5], [3, 2]], [[5, 2]], [[2, 4], [3, 3]], [[2, 6], [3, 2]], [[7, 2]], [[2, 5], [3, 3]], [[13, 2]], [[2, 7], [3, 2]]]
  21. sub check_valuation ($n, $p) {
  22. if ($p == 2) {
  23. return valuation($n, $p) < 7;
  24. }
  25. if ($p == 3) {
  26. return valuation($n, $p) < 3;
  27. }
  28. #~ if ($p == 5) {
  29. #~ return valuation($n, $p) < 2;
  30. #~ }
  31. #~ if ($p == 7) {
  32. #~ return valuation($n, $p) < 2;
  33. #~ }
  34. #~ if ($p == 13) {
  35. #~ return valuation($n, $p) < 2;
  36. #~ }
  37. ($n % $p) != 0;
  38. }
  39. sub smooth_numbers ($limit, $primes) {
  40. my @h = (1);
  41. foreach my $p (@$primes) {
  42. say "Prime: $p";
  43. foreach my $n (@h) {
  44. if ($n * $p <= $limit and check_valuation($n, $p)) {
  45. if (!ref($n) and $n * $p > ~0) {
  46. my $t = Math::GMPz::Rmpz_init_set_ui($n);
  47. Math::GMPz::Rmpz_mul_ui($t, $t, $p);
  48. push @h, $t;
  49. }
  50. else {
  51. push @h, $n * $p;
  52. }
  53. }
  54. }
  55. }
  56. return \@h;
  57. }
  58. my %fib;
  59. my @fib;
  60. foreach my $n (2 .. 150) {
  61. my $k = lucasu(1, -1, $n);
  62. $fib{$k} = 1;
  63. push @fib, $k;
  64. }
  65. sub isok ($n) {
  66. my $count = 0;
  67. foreach my $f(@fib) {
  68. last if ($f > $n);
  69. if ($n % $f == 0) {
  70. ++$count;
  71. }
  72. }
  73. return $count;
  74. #scalar grep { exists($fib{$_}) } divisors($n);
  75. }
  76. my @smooth_primes;
  77. foreach my $p (@{primes(4801)}) {
  78. if ($p == 2) {
  79. push @smooth_primes, $p;
  80. next;
  81. }
  82. my @f1 = factor($p - 1);
  83. my @f2 = factor($p + 1);
  84. if ($f1[-1] <= 7 and $f2[-1] <= 7) {
  85. push @smooth_primes, $p;
  86. }
  87. }
  88. #@smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67);
  89. #@smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47);
  90. #@smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 47, 61, 89);
  91. #@smooth_primes = (2, 3, 5, 13, 7, 17, 11, 89, 233, 29, 61, 47, 1597, 19, 37, 113, 41);
  92. #@smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 47, 61, 89);
  93. #@smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 47, 53, 61, 89, 107, 109, 113);
  94. @smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 47, 61, 89, 107, 211, 421);
  95. #@smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 29, 37, 41, 47, 61, 89, 113, 233, 1597);
  96. #@smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 47, 61, 89, 107, 211, 421, 73, 149, 2221);
  97. #@smooth_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 47, 53, 61, 89, 107);
  98. # Candidate primes:
  99. # 2, 3, 5, 13, 7, 17, 11, 89, 29, 61, 47, 19, 37, 41, 23, 53, 31, 73, 43, 97, 59, 67, 71, 79, 83
  100. # Factors of smooth Fibonacci numbers:
  101. # 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 47, 53, 61, 89, 107, 109, 113
  102. #@smooth_primes = (2, 3, 5, 13, 7, 17, 11, 89, 29, 61, 47, 19, 37, 41, 23, 53, 31, 73);
  103. #@smooth_primes = (2, 3, 5, 13, 7, 17, 11, 89, 29, 61, 47, 19, 37, 41, 23, 53, 31);
  104. #@smooth_primes = grep { $_ <= 61 } @smooth_primes;
  105. #@smooth_primes = (2, 3, 5, 13, 7, 17, 11, 89, 29, 61, 47, 19, 37, 41, 23, 53, 31, 73, 43, 97, 59, 67, 71, 79, 83);
  106. my $h = smooth_numbers(2871823595953313027488381920, \@smooth_primes);
  107. say "\nFound: ", scalar(@$h), " terms";
  108. my %table;
  109. my $a18 = Math::GMPz->new("100713612963105061920");
  110. my $a19 = Math::GMPz->new("32329069761156724876320");
  111. my $a20 = Math::GMPz->new("8946490953125585755415520");
  112. my $a21 = Math::GMPz->new("2871823595953313027488381920");
  113. foreach my $n (@$h) {
  114. next if $n < 12732356276640;
  115. my $p = isok($n);
  116. if ($p >= 15) {
  117. if (!exists($table{$p}) or $n < $table{$p}) {
  118. say "a($p) = $n -> ", join(' * ', map { "$_->[0]^$_->[1]" } factor_exp($n));
  119. $table{$p} = $n;
  120. }
  121. if ($p == 15 and $n < 523410559111440) {
  122. die "NEW: a(15) <= $n";
  123. }
  124. if ($p == 16 and $n < 24076885719126240) {
  125. die "New: a(16) <= $n";
  126. }
  127. if ($p == 17 and $n < 1131613628798933280) {
  128. die "New: a(17) <= $n";
  129. }
  130. if ($p == 18 and $n < $a18) {
  131. die "New: a(18) <= $n";
  132. }
  133. if ($p == 19 and $n < $a19) {
  134. die "New: a(19) <= $n";
  135. }
  136. if ($p == 20 and $n < $a20) {
  137. die "New: a(20) <= $n";
  138. }
  139. if ($p == 21 and $n < $a21) {
  140. die "New: a(21) <= $n";
  141. }
  142. if ($p > 21) {
  143. die "New upper-bound: a($p) <= $n";
  144. }
  145. }
  146. }
  147. say '';
  148. foreach my $k (sort { $a <=> $b } keys %table) {
  149. say "a($k) <= ", $table{$k};
  150. }