r.pl 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #!/usr/bin/perl
  2. # a(n) is the least prime p for which the continued fraction expansion of sqrt(p) has exactly n consecutive 1's starting at position 2.
  3. # https://oeis.org/A307453
  4. # a(30) = 326757090818617
  5. # Algorithm from:
  6. # http://web.math.princeton.edu/mathlab/jr02fall/Periodicity/mariusjp.pdf
  7. use 5.010;
  8. use strict;
  9. use warnings;
  10. use ntheory qw(is_prime);
  11. use Math::GMPz;
  12. sub isok {
  13. my ($n, $want) = @_;
  14. $n = Math::GMPz->new("$n");
  15. my $x = Math::GMPz::Rmpz_init();
  16. Math::GMPz::Rmpz_sqrt($x, $n);
  17. return 0 if Math::GMPz::Rmpz_perfect_square_p($n);
  18. my $y = Math::GMPz::Rmpz_init_set($x);
  19. my $z = Math::GMPz::Rmpz_init_set_ui(1);
  20. my $r = Math::GMPz::Rmpz_init();
  21. my @cfrac = ($x);
  22. Math::GMPz::Rmpz_add($r, $x, $x); # r = x+x
  23. my $count = 0;
  24. do {
  25. my $t = Math::GMPz::Rmpz_init();
  26. # y = (r*z - y)
  27. Math::GMPz::Rmpz_submul($y, $r, $z); # y = y - t*z
  28. Math::GMPz::Rmpz_neg($y, $y); # y = -y
  29. # z = floor((n - y*y) / z)
  30. Math::GMPz::Rmpz_mul($t, $y, $y); # t = y*y
  31. Math::GMPz::Rmpz_sub($t, $n, $t); # t = n-t
  32. Math::GMPz::Rmpz_divexact($z, $t, $z); # z = t/z
  33. # t = floor((x + y) / z)
  34. Math::GMPz::Rmpz_add($t, $x, $y); # t = x+y
  35. Math::GMPz::Rmpz_tdiv_q($t, $t, $z); # t = floor(t/z)
  36. $r = $t;
  37. #push @cfrac, $t;
  38. ++$count;
  39. if ($count <= $want) {
  40. Math::GMPz::Rmpz_cmp_ui($t, 1) == 0 or return 0;
  41. }
  42. elsif ($count == $want+1) {
  43. return (Math::GMPz::Rmpz_cmp_ui($t, 1) != 0);
  44. }
  45. } until (Math::GMPz::Rmpz_cmp_ui($z, 1) == 0);
  46. return 0;
  47. }
  48. #~ use ntheory qw(forprimes);
  49. #~ my $k = 1;
  50. #~ my $want = 2;
  51. #~ local $| = 1;
  52. #~ while (1) {
  53. #~ ++$k;
  54. #~ if (isok($k, $want)) {
  55. #~ print "$k, ";
  56. #~ ++$want;
  57. #~ $k = 1;
  58. #~ }
  59. #~ }
  60. #~ __END__
  61. # Limit_{n->infinity} (sqrt(a(n)) - floor(sqrt(a(n)))) = A094214.
  62. use Math::AnyNum qw(phi round floor PREC 1024);
  63. my $k = 1;
  64. my $want = 3;
  65. local $| = 1;
  66. while (1) {
  67. ++$k;
  68. my $n = round(($k + phi - 1)**2);
  69. # is_prime($n) || next;
  70. if (isok($n, $want)) {
  71. print "$n, ";
  72. $k = 1;
  73. ++$want;
  74. }
  75. }
  76. # 7, 13, 244, 58, 135, 3921, 819, 2081, 68444, 13834, 35955, 1220181, 244647, 639389, 21861404, 4374866, 11448871, 392143681, 78439683
  77. # 7, 13, 3797, 5273, 4987, 90371, 79873, 2081, 111301, 1258027, 5325101, 12564317, 9477889, 47370431, 709669249, 1529640443, 2196104969, 392143681, 8216809361, 30739072339, 200758317433,
  78. # 7, 13, 3797, 5273, 4987, 90371, 79873, 2081, 111301, 1258027, 5325101, 12564317, 9477889, 47370431, 709669249, 1529640443, 2196104969, 392143681
  79. # 7, 13, 3797, 5273, 4987, 90371, 79873, 2081, 111301, 1258027, 5325101, 12564317, 9477889, 47370431, 709669249, 1529640443, 2196104969, 392143681
  80. #my @arr = ( 3, 31, 7, 13, 3797, 5273, 4987, 90371, 79873, 2081, 111301, 1258027, 5325101, 12564317, 9477889, 47370431, 709669249, 1529640443, 2196104969, 392143681);
  81. #foreach my $k(0..$#arr) {
  82. # say isok($arr[$k], $k+1);
  83. #}
  84. __END__
  85. 7, 13, 3797, 5273, 4987, 90371, 79873, 2081, 111301, 1258027, 5325101, 12564317, 9477889, 47370431, 709669249, 1529640443, 2196104969, 392143681, 8216809361, 30739072339, 200758317433, 370949963971, 161356959383, 1788677860531, 7049166342469, 4484287435283, 3690992602753, ^C
  86. perl r.pl 286.67s user 0.16s system 99% cpu 4:48.23 total
  87. sqrt(1) = [1]
  88. sqrt(2) = [1, 2]
  89. sqrt(3) = [1, 1, 2]
  90. sqrt(4) = [2]
  91. sqrt(5) = [2, 4]
  92. sqrt(6) = [2, 2, 4]
  93. sqrt(7) = [2, 1, 1, 1, 4]
  94. sqrt(8) = [2, 1, 4]
  95. sqrt(9) = [3]
  96. sqrt(10) = [3, 6]
  97. sqrt(11) = [3, 3, 6]
  98. sqrt(12) = [3, 2, 6]
  99. sqrt(13) = [3, 1, 1, 1, 1, 6]
  100. sqrt(14) = [3, 1, 2, 1, 6]
  101. sqrt(15) = [3, 1, 6]
  102. sqrt(16) = [4]
  103. sqrt(17) = [4, 8]
  104. sqrt(18) = [4, 4, 8]
  105. sqrt(19) = [4, 2, 1, 3, 1, 2, 8]
  106. sqrt(20) = [4, 2, 8]