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