r.pl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 12 January 2019
  4. # https://github.com/trizen
  5. # Generate the entire sequence of both-truncatable primes in a given base between 3 and 36.
  6. # Maximum value for each base is given in the following OEIS sequence:
  7. # https://oeis.org/A323137
  8. # a(17) = 631
  9. # a(18) = ?
  10. # See also:
  11. # https://www.youtube.com/watch?v=azL5ehbw_24
  12. # https://en.wikipedia.org/wiki/Truncatable_prime
  13. use 5.010;
  14. use strict;
  15. use warnings;
  16. #use Math::AnyNum;
  17. use ntheory qw(fromdigits is_prob_prime vecmax);
  18. use Math::GMPz;
  19. my $limit = Math::GMPz->new(10)**18;
  20. # 202715129
  21. sub is_right_truncatable {
  22. my ($n, $base) = @_;
  23. while (length($n) > 0) {
  24. is_prob_prime(fromdigits($n, $base)) || return 0;
  25. chop $n;
  26. }
  27. return 1;
  28. }
  29. sub is_left_truncatable {
  30. my ($n, $base) = @_;
  31. while (length($n) > 0) {
  32. is_prob_prime(fromdigits($n, $base)) || return 0;
  33. $n = substr($n, 1);
  34. }
  35. return 1;
  36. }
  37. sub left_truncatable_primes {
  38. my ($p, $base, $digits) = @_;
  39. # if (not is_right_truncatable($p, $base)) {
  40. # return ();
  41. # }
  42. #say "left: $p";
  43. my @seq = ($p);
  44. foreach my $n (@$digits) {
  45. my $next = "$n$p";
  46. my $q = (fromdigits($next, $base));
  47. if (is_prob_prime($q) && $q < $limit) {
  48. push @seq, left_truncatable_primes($next, $base, $digits);
  49. }
  50. # }
  51. }
  52. return @seq;
  53. }
  54. sub right_truncatable_primes {
  55. my ($p, $base, $digits) = @_;
  56. #if (not is_left_truncatable($p, $base)) {
  57. # return ();
  58. # }
  59. #say "right: $p";
  60. my @seq = ($p);
  61. foreach my $n (@$digits) {
  62. my $next = "$p$n";
  63. my $q = (fromdigits($next, $base));
  64. if (is_prob_prime($q) && $q < $limit) {
  65. push @seq, right_truncatable_primes($next, $base, $digits);
  66. }
  67. }
  68. return @seq;
  69. }
  70. sub both_truncatable_primes_in_base {
  71. my ($base) = @_;
  72. if ($base < 3 or $base > 36) {
  73. die "error: base must be between 3 and 36\n";
  74. }
  75. my @digits = (1 .. $base - 1);
  76. if ($base > 10) {
  77. @digits = (1 .. 9);
  78. my $letter = 'a';
  79. for (1 .. $base - 10) {
  80. push @digits, $letter;
  81. ++$letter;
  82. }
  83. }
  84. my @d = grep { is_prob_prime(fromdigits($_, $base)) } @digits;
  85. my %left;
  86. my %right;
  87. foreach my $p (@d) {
  88. say "Left: $p -> ", scalar(keys %left);
  89. @left{left_truncatable_primes($p, $base, \@digits)} = ();
  90. say "Right: $p", scalar(keys %right);
  91. @right{right_truncatable_primes($p, $base, \@digits)} = ();
  92. }
  93. map { fromdigits($_, $base) } grep { exists($right{$_}) } keys(%left);
  94. }
  95. foreach my $base (18) {
  96. say "Largest both-truncatable prime in base $base is: ", vecmax(both_truncatable_primes_in_base($base));
  97. }
  98. __END__
  99. Largest both-truncatable prime in base 3 is: 23
  100. Largest both-truncatable prime in base 4 is: 11
  101. Largest both-truncatable prime in base 5 is: 67
  102. Largest both-truncatable prime in base 6 is: 839
  103. Largest both-truncatable prime in base 7 is: 37
  104. Largest both-truncatable prime in base 8 is: 1867
  105. Largest both-truncatable prime in base 9 is: 173
  106. Largest both-truncatable prime in base 10 is: 739397
  107. Largest both-truncatable prime in base 11 is: 79
  108. Largest both-truncatable prime in base 12 is: 105691
  109. Largest both-truncatable prime in base 13 is: 379
  110. Largest both-truncatable prime in base 14 is: 37573
  111. Largest both-truncatable prime in base 15 is: 647
  112. Largest both-truncatable prime in base 16 is: 3389
  113. Largest both-truncatable prime in base 17 is: 631