Find largest left truncatable prime in a given base: Difference between revisions

m
(Added Maple Code)
m (→‎{{header|Wren}}: Minor tidy)
 
(30 intermediate revisions by 14 users not shown)
Line 1:
{{task|Prime Numbers}}
 
A [[Truncatable primes|truncatable prime]] is one where all non-empty substrings that finish at the end of the number (right-substrings) are also primes ''when understood as numbers in a particular base''. The largest such prime in a given (integer) base is therefore computable, provided the base is larger than 2.
Line 18:
{{works with|BBC BASIC for Windows}}
Uses the '''H'''uge '''I'''nteger '''M'''ath & '''E'''ncryption library from http://devotechs.com/
<langsyntaxhighlight lang="bbcbasic"> HIMEM = PAGE + 3000000
INSTALL @lib$+"HIMELIB"
PROC_himeinit("HIMEkey")
Line 58:
SWAP old%, new%
UNTIL old% = 0
= new$(new%-1)</langsyntaxhighlight>
'''Output:'''
<pre>
Line 79:
 
=={{header|C}}==
{{libheader|GMP}}
<lang c>#include <stdio.h>
<syntaxhighlight lang="c">#include <stdio.h>
#include <gmp.h>
 
Line 142 ⟶ 143:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 156 ⟶ 157:
...
</pre>
 
=={{header|C sharp|C#}}==
<syntaxhighlight lang="csharp">using Mpir.NET; // 0.4.0
using System; // 4790@3.6
using System.Collections.Generic;
class MaxLftTrP_B
{
static void Main()
{
mpz_t p; var sw = System.Diagnostics.Stopwatch.StartNew(); L(3);
for (uint b = 3; b < 13; b++)
{
sw.Restart(); p = L(b);
Console.WriteLine("{0} {1,2} {2}", sw.Elapsed, b, p);
}
Console.Read();
}
 
static mpz_t L(uint b)
{
var p = new List<mpz_t>(); mpz_t np = 0;
while ((np = nxtP(np)) < b) p.Add(np);
int i0 = 0, i = 0, i1 = p.Count - 1; mpz_t n0 = b, n, n1 = b * (b - 1);
for (; i < p.Count; n0 *= b, n1 *= b, i0 = i1 + 1, i1 = p.Count - 1)
for (n = n0; n <= n1; n += n0)
for (i = i0; i <= i1; i++)
if (mpir.mpz_probab_prime_p(np = n + p[i], 15) > 0) p.Add(np);
return p[p.Count - 1];
}
 
static mpz_t nxtP(mpz_t n) { mpz_t p = 0; mpir.mpz_nextprime(p, n); return p; }
}</syntaxhighlight>
{{out}}
<pre>
00:00:00.0000082 3 23
00:00:00.0000267 4 4091
00:00:00.0000299 5 7817
00:00:00.0027235 6 4836525320399
00:00:00.0000533 7 817337
00:00:00.0026306 8 14005650767869
00:00:00.0004923 9 1676456897
00:00:00.0514316 10 357686312646216567629137
00:00:00.0003609 11 2276005673
00:00:03.3792076 12 13092430647736190817303130065827539
</pre>
 
=={{header|C++}}==
{{trans|C}}
<syntaxhighlight lang="cpp">#include <gmpxx.h>
 
#include <algorithm>
#include <cassert>
#include <functional>
#include <iostream>
#include <vector>
 
using big_int = mpz_class;
 
const unsigned int small_primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23,
29, 31, 37, 41, 43, 47, 53, 59, 61,
67, 71, 73, 79, 83, 89, 97};
 
bool is_probably_prime(const big_int& n, int reps) {
return mpz_probab_prime_p(n.get_mpz_t(), reps) != 0;
}
 
big_int largest_left_truncatable_prime(unsigned int base) {
std::vector<big_int> powers = {1};
std::vector<big_int> value = {0};
big_int result = 0;
 
std::function<void(unsigned int)> add_digit = [&](unsigned int i) {
if (i == value.size()) {
value.resize(i + 1);
powers.push_back(base * powers.back());
}
for (unsigned int d = 1; d < base; ++d) {
value[i] = value[i - 1] + powers[i] * d;
if (!is_probably_prime(value[i], 1))
continue;
if (value[i] > result) {
if (!is_probably_prime(value[i], 50))
continue;
result = value[i];
}
add_digit(i + 1);
}
};
 
for (unsigned int i = 0; small_primes[i] < base; ++i) {
value[0] = small_primes[i];
add_digit(1);
}
return result;
}
 
int main() {
for (unsigned int base = 3; base < 18; ++base) {
std::cout << base << ": " << largest_left_truncatable_prime(base)
<< '\n';
}
for (unsigned int base = 19; base < 32; base += 2) {
std::cout << base << ": " << largest_left_truncatable_prime(base)
<< '\n';
}
}</syntaxhighlight>
 
{{out}}
<pre>
3: 23
4: 4091
5: 7817
6: 4836525320399
7: 817337
8: 14005650767869
9: 1676456897
10: 357686312646216567629137
11: 2276005673
12: 13092430647736190817303130065827539
13: 812751503
14: 615419590422100474355767356763
15: 34068645705927662447286191
16: 1088303707153521644968345559987
17: 13563641583101
19: 546207129080421139
21: 391461911766647707547123429659688417
23: 116516557991412919458949
25: 8211352191239976819943978913
27: 10681632250257028944950166363832301357693
29: 4300289072819254369986567661
31: 645157007060845985903112107793191
</pre>
 
=={{header|Eiffel}}==
As there is currently no implementation for arbitrary precision integers this example only works for base 3 to base 9. Respectively for bases where the Result fits into a INTEGER_64.
<syntaxhighlight lang="eiffel">
<lang Eiffel>
class
LARGEST_LEFT_TRUNCABLE_PRIME
Line 281 ⟶ 415:
 
end
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 294 ⟶ 428:
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">
(* Find some probable candidates for The Largest Left Trucatable Prime in a given base
Nigel Galloway: April 25th., 2017 *)
Line 307 ⟶ 441:
if (Array.isEmpty g) then n else (fi g (i*Fbase))
pZ |> Array.Parallel.map (fun n -> fi [|n|] Fbase)|>Seq.concat|>Seq.max
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 344 ⟶ 478:
The source file uses the F90 style, mainly because module PRIMEBAG (from [[Extensible_prime_generator#Fortran]]) is available to supply some prime numbers and check whether a number is prime or not. This works up to the 32-bit integer limit: although INTEGER*8 variables are available, that seemed a reasonable stopping point. Otherwise, the source is older-style, except for a few conveniences: the use of "CYCLE" rather than a "GO TO", some array assignments rather than explicit DO-loops, and the special function MAXLOC to locate the index of the maximum value in an array. Although F90 also allows arrays of compound data, the entries are stored via a two-dimensional array, and to keep related digits adjacent in storage the indexing is (digit,entry) rather than (entry,digit) since fortran uses that ordering.
 
Unfortunately, the modernisers have abandoned a feature of First Fortran (1957): the <code>IF OVERFLOW ... </code> statement, or similar. In its place are ad-hoc tests on whether a number has suddenly become zero or negative: there is roughly a 50:50 chance that an overflow in two's-complement integer arithmetic will produce such a result - if positive, the value will still be wrong after an overflow. Such checks are tedious, but not bothering to check will mean that odd behaviour will ensue, and worse, incorrect results. <langsyntaxhighlight Fortranlang="fortran"> USE PRIMEBAG !Gain access to NEXTPRIME and ISPRIME.
Calculates the largest "left-truncatable" digit sequence that is a prime number, in various bases.
INTEGER LBASE,MANY,ENUFF !Some sizes.
Line 425 ⟶ 559:
 
END DO !On to the next base.
END !Simple enough.</langsyntaxhighlight>
 
Results:
Line 445 ⟶ 579:
</pre>
 
So, there being no type declarations such as INTEGER*600, multi-precision arithmetic is needed to go further. There is no universally-used library for this, but thanks to previous effort in [[Sequence_of_primorial_primes#Fortran]] a collection is available, another F90 "module". This however works with a fixed value of BIGBASE, which is expected to be a large number and a power of ten. While there would be no great difficulty in converting from the digit sequences in the current base into a BIGNUM in base BIGBASE, it is more interesting to work with the desired base so that the digit sequences are manipulated directly. Accordingly, a variation, with the module starting <langsyntaxhighlight Fortranlang="fortran"> MODULE BIGNUMBERVB !Limited services: integers, no negative numbers, variable base possible.
INTEGER BIGORDER !A limited attempt at generality.
PARAMETER (BIGORDER = 1) !This is the order of the base of the big number arithmetic.
Line 455 ⟶ 589:
INTEGER DIGIT(BIGLIMIT) !The digits, in ascending power order.
END TYPE BIGNUM !So much for that.
</syntaxhighlight>
</lang>
 
As checked via earlier tests, using a fixed value for BIGLIMIT that is "surely big enough" enables faster execution than variable sizes. Now, BIGBASE is a variable, with a view to <code>DO BIGBASE = 3,17</code> and almost everything else remains the same, though with BIGBASE being a rather small number, there is no need to employ 64-bit variables via INTEGER*8 at certain places. The use of BIGORDER is disrupted and routines employing it should be avoided or adjusted, thus in BIGTASTE, adding <langsyntaxhighlight Fortranlang="fortran"> IF (MOD(BIGBASE,10).NE.0) STOP "BIGTASTE expects powers of 10" !Alas. Otherwise the "E" formalism fails.</langsyntaxhighlight> for example. The changes produce <langsyntaxhighlight Fortranlang="fortran"> SUBROUTINE BIGWRITE(F,B) !Show B.
INTEGER F !I/O unit number.
TYPE(BIGNUM) B !The number.
Line 485 ⟶ 619:
BIGISPRIME = ABS(BIGFACTOR(B,2800)).EQ.1 !Condensed report.
END FUNCTION BIGISPRIME !Can't be bothered with ISPRIME from PRIMEBAG.
</syntaxhighlight>
</lang>
Which is to say that BIGWRITE will show the digits of a number as decimal numbers separated by periods rather than involving letters as additional digit symbols, while BIGTEN will prepare a text version in base ten, whatever BIGBASE is. Finally, BIGMRPRIME used to quit if BIGBASE were less than four, because it wants to test numbers not exceeding four by only inspecting a single digit of the big number, so that it can for larger numbers perform a direct test for divisibility by two and three without rejecting those numbers as primes just in case it is invoked for them. So ... <langsyntaxhighlight Fortranlang="fortran">Catch some annoying cases, to protect the direct tests for divisibility by two and three...
IF (N.LAST.LE.2) THEN !A smallish number? I want to compare to four, but BIGBASE might be two.
NR = BIGVALUE(N) !Surely so.
Line 497 ⟶ 631:
IF (BIGMOD2(N).EQ.0) RETURN !A single expression using .OR. risks always evaluating BOTH parts, damnit,
IF (BIGMODN(N,3).EQ.0) RETURN !Even for even numbers. Possibly doing so "in parallel" is no consolation.
</syntaxhighlight>
</lang>
With all this in hand, the job can be done by <langsyntaxhighlight Fortranlang="fortran"> USE PRIMEBAG !Gain access to NEXTPRIME and ISPRIME.
USE BIGNUMBERVB !Alas, INTEGER*600 is not available.
Calculates the largest "left-truncatable" digit sequence that is a prime number, in various bases.
Line 589 ⟶ 723:
WRITE (MSG,*) "CPU time:",T1 - T0 !The cost.
END !Simple enough.
</syntaxhighlight>
</lang>
 
And the results, slightly edited to remove six columns of spaces...
Line 649 ⟶ 783:
Count: 97667 44905 44904 44904 44904 44904
CPU time: 111.2656
</pre>
 
=={{header|Go}}==
{{trans|C}}
 
 
Note that the use of ProbablyPrime(0) requires Go 1.8 or later.
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"math/big"
)
 
var smallPrimes = [...]int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29}
 
const maxStack = 128
 
var (
tens, values [maxStack]big.Int
bigTemp, answer = new(big.Int), new(big.Int)
base, seenDepth int
)
 
func addDigit(i int) {
for d := 1; d < base; d++ {
values[i].Set(&values[i-1])
bigTemp.SetUint64(uint64(d))
bigTemp.Mul(bigTemp, &tens[i])
values[i].Add(&values[i], bigTemp)
if !values[i].ProbablyPrime(0) {
continue
}
if i > seenDepth || (i == seenDepth && values[i].Cmp(answer) == 1) {
if !values[i].ProbablyPrime(0) {
continue
}
answer.Set(&values[i])
seenDepth = i
}
addDigit(i + 1)
}
}
 
func doBase() {
answer.SetUint64(0)
tens[0].SetUint64(1)
bigTemp.SetUint64(uint64(base))
seenDepth = 0
for i := 1; i < maxStack; i++ {
tens[i].Mul(&tens[i-1], bigTemp)
}
for i := 0; smallPrimes[i] < base; i++ {
values[0].SetUint64(uint64(smallPrimes[i]))
addDigit(1)
}
fmt.Printf("%2d: %s\n", base, answer.String())
}
 
func main() {
for base = 3; base <= 17; base++ {
doBase()
}
}</syntaxhighlight>
 
{{out}}
<pre>
3: 23
4: 4091
5: 7817
6: 4836525320399
7: 817337
8: 14005650767869
9: 1676456897
10: 357686312646216567629137
11: 2276005673
12: 13092430647736190817303130065827539
13: 812751503
14: 615419590422100474355767356763
15: 34068645705927662447286191
16: 1088303707153521644968345559987
17: 13563641583101
</pre>
 
=={{header|Haskell}}==
Miller-Rabin test code from [http://www.haskell.org/haskellwiki/Testing_primality#Miller-Rabin_Primality_Test HaskellWiki], with modifications.
<langsyntaxhighlight lang="haskell">primesTo100 = [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97]
 
-- (eq. to) find2km (2^k * n) = (k,n)
Line 718 ⟶ 934:
addDigit a = filter (is_prime [3]) $ map (a*b+) x
 
main = mapM_ print $ map (\x->(x, left_trunc x)) [3..21]</langsyntaxhighlight>
<pre>
(3,23)
Line 743 ⟶ 959:
=={{header|J}}==
 
<langsyntaxhighlight Jlang="j">ltp=:3 :0
probe=. i.1 0
while. #probe do.
Line 749 ⟶ 965:
end.
>./y#.have
)</langsyntaxhighlight>
 
Quick example:
 
<langsyntaxhighlight Jlang="j"> (,ltp)"0]3 4 5 6 7 8 9 10 11
3 23
4 4091
Line 762 ⟶ 978:
9 1676456897
10 992429121339693967
11 2276005673</langsyntaxhighlight>
 
Representation of a current longer effort:
 
<langsyntaxhighlight Jlang="j"> (,ltp)"0]3}.i.20x
3 23
4 4091
Line 783 ⟶ 999:
17 13563641583101
18 571933398724668544269594979167602382822769202133808087
19 546207129080421139</langsyntaxhighlight>
 
=={{header|Java}}==
 
'''Code:'''
<syntaxhighlight lang="java">import java.math.BigInteger;
 
<lang java>import java.math.BigInteger;
import java.util.*;
 
Line 826 ⟶ 1,040:
public static void main(String[] args)
{
if (args.length != 2) {
int maxRadix = Integer.parseInt(args[0]);
System.err.println("There must be exactly two command line arguments.");
int millerRabinCertainty = Integer.parseInt(args[1]);
return;
}
int maxRadix;
try {
maxRadix = Integer.parseInt(args[0]);
if (maxRadix < 3) throw new NumberFormatException();
} catch (NumberFormatException e) {
System.err.println("Radix must be an integer greater than 2.");
return;
}
int millerRabinCertainty;
try {
millerRabinCertainty = Integer.parseInt(args[1]);
} catch (NumberFormatException e) {
System.err.println("Miiller-Rabin Certainty must be an integer.");
return;
}
for (int radix = 3; radix <= maxRadix; radix++)
{
Line 839 ⟶ 1,070:
}
}</langsyntaxhighlight>
 
'''Example:'''
 
<pre>java LeftTruncatablePrime 17 1000000100
n=3: 23 (in base 3): 212
n=4: 4091 (in base 4): 333323
Line 861 ⟶ 1,092:
 
=={{header|Julia}}==
This solution keeps candidate values in an array. A new digit is added with each generation, removing the previous generation's primes from the front of the list (<tt>shiftpopfirst!</tt>) and adding new candidates to the end of the list (<tt>append!</tt>) with each generation. The maximum value yielded in each generation is tracked as a provisional answer. Once the array is emptied (because no digit could be added to any of the previous generation's primes to yield a prime), the algorithm is finished and the answer found.
 
This solution is limited to a base of 17, to keep the processing time to well under a minute (about 15 seconds on an old but decent quality notebook). (I've let it run to as high as 23, but that took something like 20 minutes as I was otherwise occupied.) I did attempt a few optimizations of this general approach (such as moving the logic of <tt>addmsdigit</tt> into <tt>lefttruncprime</tt> and being clever about identifying the maximum of a given generation) but none of these tweaks resulted in a significant improvement in efficiency.
<syntaxhighlight lang="julia">using Primes, Printf
<lang Julia>
function addmsdigit{T<:Integer}(p::T, b::T, s::T)
function addmsdigit(p::Integer, b::Integer, s::Integer)
a = T[]
a = Vector{typeof(p)}()
q = p
for i in 1:(b-1)
Line 875 ⟶ 1,107:
return a
end
 
function lefttruncprime{T<:Integer}(pbase::TInteger)
ba = convertVector{BigInt}(BigInt, pbase)
append!(a, primes(pbase - 1))
a = BigInt[]
append!(a, primes(b-1))
mlt = zero(BigInt)
s = one(BigInt)
while !isempty(a)
mlt = maximum(a)
s *= bpbase
for i in 1:length(a)
p = shiftpopfirst!(a)
append!(a, addmsdigit(p, bpbase, s))
end
end
return mlt
end
 
lo, hi = 3, 17
printprintln("The largest left truncatable primes for bases", @sprintf(" %d to %d.", lo, hi))
println(@sprintf " %d to %d." lo hi)
for i in lo:hi
mlt = lefttruncprime(i)
println@printf(@sprintf " %3d10d %d-30d (%s)\n", i, mlt, basestring(imlt, mltbase=i))
end
</syntaxhighlight>{{out}}
</lang>
 
{{out}}
<pre>
The largest left truncatable primes for bases 3 to 17.
Line 924 ⟶ 1,152:
=={{header|Kotlin}}==
{{trans|Java}}
<langsyntaxhighlight lang="scala">// version 1.1.2
 
import java.math.BigInteger
Line 964 ⟶ 1,192:
println("${largest.toString().padEnd(35)} -> ${largest.toString(radix)}")
}
}</langsyntaxhighlight>
 
{{out}}
Line 988 ⟶ 1,216:
Base = 17 : 13563641583101 -> 6c66cc4cc83
</pre>
 
=={{header|Maple}}==
<syntaxhighlight lang="maple">MaxLeftTruncatablePrime := proc(b, $)
local i, j, c, p, sdprimes;
local tprimes := table();
sdprimes := select(isprime, [seq(1..b-1)]);
for p in sdprimes do
if assigned(tprimes[p]) then
next;
end if;
i := ilog[b](p)+1;
j := 1;
do
c := j*b^i + p;
if j >= b then
# we have tried all 1 digit extensions of p, add p to tprimes and move back 1 digit
tprimes[p] := p;
if i = 1 then
# if we are at the first digit, go to the next 1 digit prime
break;
end if;
i := i - 1;
j := 1;
p := p - iquo(p, b^i)*b^i;
elif assigned(tprimes[c]) then
j := j + 1;
elif isprime(c) then
p := c;
i := i + 1;
j := 1;
else
j := j+1;
end if;
end do;
end do;
return max(indices(tprimes, 'nolist'));
end proc;</syntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
 
<syntaxhighlight lang="text">LargestLeftTruncatablePrimeInBase[n_] :=
Max[NestWhile[{Select[
Flatten@Outer[Function[{a, b}, #[[2]] a + b],
Range[1, n - 1], #[[1]]], PrimeQ], n #[[2]]} &, {{0},
1}, #[[1]] != {} &, 1, Infinity, -1][[1]]]</langsyntaxhighlight>
 
Example:
 
<syntaxhighlight lang="text">Do[Print[n, "\t", LargestLeftTruncatablePrimeInBase@n], {n, 3, 17}]</langsyntaxhighlight>
 
Output:
Line 1,033 ⟶ 1,298:
17 13563641583101</pre>
 
=={{header|MapleNim}}==
{{libheader|bignum}}
<lang maple>MaxLeftTruncatablePrime := proc(b, $)
<syntaxhighlight lang="nim">import bignum, strformat
local i, j, c, p, sdprimes;
 
local tprimes := table();
const
sdprimes := select(isprime, [seq(1..b-1)]);
 
for p in sdprimes do
Primes = [2, 3, 5, 7, 11, 13, 17]
if assigned(tprimes[p]) then
Digits = "0123456789abcdefghijklmnopqrstuvwxyz"
next;
 
end if;
#---------------------------------------------------------------------------------------------------
i := ilog[b](p)+1;
 
j := 1;
func isProbablyPrime(n: Int): bool =
do
## Return true if "n" is not definitively composite.
c := j*b^i + p;
probablyPrime(n, 25) != 0
if j >= b then
 
# we have tried all 1 digit extensions of p, add p to tprimes and move back 1 digit
#---------------------------------------------------------------------------------------------------
tprimes[p] := p;
 
if i = 1 then
func maxLeftTruncablePrime(base: int): Int =
# if we are at the first digit, go to the next 1 digit prime
## Return the maximum left truncable prime for given base.
break;
 
end if;
let base = base.int32
i := i - 1;
var primes: seq[Int]
j := 1;
 
p := p - iquo(p, b^i)*b^i;
# Initialize primes with one digit in given base.
elif assigned(tprimes[c]) then
for p in Primes:
j := j + 1;
if p < base:
elif isprime(c) then
primes.add(newInt(p := c;))
else:
i := i + 1;
j := 1;break
 
else
# Build prime list with one more digit per generation.
j := j+1;
var next: seq[Int]
end if;
while true:
end do;
 
end do;
# Build the next generation (with one more digit).
return max(indices(tprimes, 'nolist'));
for p in primes:
end proc;</lang>
var pstr = ' ' & `$`(p, base) # ' ' as a placeholder for next digit.
for i in 1..<base:
pstr[0] = Digits[i]
let n = newInt(pstr, base)
if n.isProbablyPrime():
next.add(n)
 
if next.len == 0:
# No primes with this number of digits.
# Return the greatest prime in previous generation.
return max(primes)
 
# Prepare to build next generation.
primes = next
next.setLen(0)
 
#———————————————————————————————————————————————————————————————————————————————————————————————————
 
echo "Base Greatest left truncable prime"
echo "====================================="
for base in 3..17:
let m = maxLeftTruncablePrime(base)
echo &"{base:>3} {m}", if base > 10: " (" & `$`(m, base.int32) & ')' else: ""</syntaxhighlight>
 
{{out}}
<pre>Base Greatest left truncable prime
=====================================
3 23
4 4091
5 7817
6 4836525320399
7 817337
8 14005650767869
9 1676456897
10 357686312646216567629137
11 2276005673 (a68822827)
12 13092430647736190817303130065827539 (471a34a164259ba16b324ab8a32b7817)
13 812751503 (cc4c8c65)
14 615419590422100474355767356763 (d967ccd63388522619883a7d23)
15 34068645705927662447286191 (6c6c2ce2ceeea4826e642b)
16 1088303707153521644968345559987 (dbc7fba24fe6aec462abf63b3)
17 13563641583101 (6c66cc4cc83)</pre>
 
=={{header|PARI/GP}}==
Takes half a second to find the terms up to 10, with proofs of primality. The time can be halved without proofs (use <code>ispseudoprime</code> in place of <code>isprime</code>).
<langsyntaxhighlight lang="parigp">a(n)=my(v=primes(primepi(n-1)),u,t,b=1,best); while(#v, best=vecmax(v); b*=n; u=List(); for(i=1,#v,for(k=1,n-1,if(isprime(t=v[i]+k*b), listput(u,t)))); v=Vec(u)); best</langsyntaxhighlight>
=={{header|Pascal}}==
==={{header|Free Pascal}}===
Using gmp and depth first search, like by [[Find_largest_left_truncatable_prime_in_a_given_base#Phix|Phix]].<br>Use preset numbers and powers of base to max values expecting that no memory-reallocations during runtime are needed.<br>
HTOP shows no variance in used memory.
<syntaxhighlight lang="pascal">
program TruncatablePrimes;
//https://rosettacode.org/wiki/Find_largest_left_truncatable_prime_in_a_given_base
{$IFDEF FPC}{$MODE DELPHI}{$OPTIMIZATION ON,ALL}{$ENDIF}
{$IFDEF Windows}{$APPTYPE CONSOLE}{$ENDIF}
uses
sysutils,gmp;// http://rosettacode.org/wiki/Extensible_prime_generator#Pascal
const
DgtToChar : array[0..10+26+26-1] of char =
'0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
MaxDgtCnt = 50;
var
pot_Base : array[0..MaxDgtCnt] of mpz_t;
Numbers : array[0..MaxDgtCnt] of mpz_t;
MAX_Found : mpz_t;
Digits,
Digits_Found: array[0..MaxDgtCnt] of byte;
gbl_Count,
Max_Pot : Uint32;
 
procedure InitAll;
var
pot : mpz_t;
MaxBase,
i : integer;
begin
MaxBase := MaxDgtCnt;
mpz_init_set_ui(pot,1);
For i := 0 to High(pot_Base) do
begin
mpz_mul_ui(pot,pot,MaxBase);
mpz_init_set(pot_Base[i],Pot);
mpz_init_set(Numbers[i],Pot);
end;
mpz_init_set(MAX_Found,pot);
mpz_set_ui(MAX_Found,0);
mpz_clear(pot);
end;
 
procedure ClearAll;
var
i : integer;
begin
For i := High(pot_Base) downto 0 do
begin
mpz_clear(pot_Base[i]);
mpz_clear(Numbers[i]);
end;
mpz_clear(MAX_Found);
end;
 
procedure InitPot(Base : byte);
var
pot : mpz_t;
i : integer;
begin
mpz_init_set_ui(pot,1);
For i := 0 to High(pot_Base) do
begin
mpz_set(pot_Base[i],Pot);
mpz_mul_ui(pot,pot,base);
end;
mpz_clear(pot);
mpz_set_ui(MAX_Found,0);
Fillchar(Digits,SizeOf(Digits),#0);
end;
 
procedure Next_Number(Base,pot : byte);
var
i : integer;
begin
inc(gbl_Count);
if pot = 0 then
mpz_set_ui(Numbers[pot],0)
else
mpz_set(Numbers[pot],Numbers[pot-1]);
For i := 1 to Base-1 do
begin
Digits[pot] := i;
mpz_add(Numbers[pot],Numbers[pot],pot_Base[pot]);
if mpz_probab_prime_p(Numbers[pot],5)>0 then
Begin
IF mpz_cmp(MAX_Found,Numbers[pot])<0 then
Begin
mpz_set(Max_Found,Numbers[pot]);
Max_pot := pot;
Digits_Found := Digits;
end;
Next_Number(Base,pot+1);
end;
end;
end;
 
var
base,i : NativeUint;
sol : pChar;
Begin
GetMem(sol,10000);
InitAll;
try
For base := 3 to 31 do
begin
IF (Base>17) AND Not(Odd(Base)) then
continue;
InitPot(base);
gbl_Count := 0;
write('Base ',base:2,' digits ');
Next_Number(base,0);
write(Max_Pot+1:4,' checks ',gbl_Count:8,' ');
if mpz_fits_ulong_p(Max_Found)<> 0 then
write(mpz_get_ui(Max_Found),' ')
else
Begin
mpz_get_str(Sol,10,Max_Found);
write(Sol,' ');
end;
For i := Max_Pot downto 0 do
write(DgtToChar[Digits_Found[i]]);
writeln;
end;
except
ClearAll;
end;
ClearAll;
FreeMem(sol);
end.
</syntaxhighlight>
{{out|@TIO.RUN}}
<pre>
Base 3 digits 3 checks 4 23 212
Base 4 digits 6 checks 17 4091 333323
Base 5 digits 6 checks 16 7817 222232
Base 6 digits 17 checks 455 4836525320399 14141511414451435
Base 7 digits 7 checks 23 817337 6642623
Base 8 digits 15 checks 447 14005650767869 313636165537775
Base 9 digits 10 checks 109 1676456897 4284484465
Base 10 digits 24 checks 4261 357686312646216567629137 357686312646216567629137
Base 11 digits 9 checks 76 2276005673 A68822827
Base 12 digits 32 checks 170054 13092430647736190817303130065827539 471A34A164259BA16B324AB8A32B7817
Base 13 digits 8 checks 101 812751503 CC4C8C65
Base 14 digits 26 checks 34394 615419590422100474355767356763 D967CCD63388522619883A7D23
Base 15 digits 22 checks 9358 34068645705927662447286191 6C6C2CE2CEEEA4826E642B
Base 16 digits 25 checks 27983 1088303707153521644968345559987 DBC7FBA24FE6AEC462ABF63B3
Base 17 digits 11 checks 363 13563641583101 6C66CC4CC83
Base 19 digits 14 checks 686 546207129080421139 CIEG86GCEA2C6H
Base 21 digits 27 checks 59132 391461911766647707547123429659688417 G8AGG2GCA8CAK4K68GEA4G2K22H
Base 23 digits 17 checks 1373 116516557991412919458949 IMMGM6C6IMCI66A4H
Base 25 digits 20 checks 10485 8211352191239976819943978913 ME6OM6OECGCC24C6EG6D
Base 27 digits 28 checks 98337 10681632250257028944950166363832301357693 O2AKK6EKG844KAIA4MACK6C2ECAB
Base 29 digits 19 checks 3927 4300289072819254369986567661 KCG66AGSCKEIASMCKKJ
Base 31 digits 22 checks 11315 645157007060845985903112107793191 UUAUIKUC4UI6OCECI642SD
 
Real time: 4.274 s User time: 4.155 s Sys. time: 0.047 s CPU share: 98.32 %</pre>
 
=={{header|Perl}}==
Line 1,079 ⟶ 1,543:
a(18) has a max candidate list of 1,449,405 entries and takes a bit over 20 minutes to solve.
{{libheader|ntheory}}
<langsyntaxhighlight lang="perl">use ntheory qw/:all/;
use Math::GMPz;
 
Line 1,098 ⟶ 1,562:
}
 
printf "%2d %s\n", $_, lltp($_) for 3 .. 17;</langsyntaxhighlight>
{{out}}
<pre>
Line 1,118 ⟶ 1,582:
</pre>
 
=={{header|Perl 6Phix}}==
{{libheader|Phix/mpfr}}
{{works with|Rakudo|2017.03}}
{{trans|C}}
Pretty fast for bases 3 .. 11. 12 is slow. 18 is glacial.
Depth-first search uses 1% of the memory of width-first search, and as a result runs about 30% faster (while still doing exactly the same actual work).
<lang perl6>for 3 .. * -> $base {
<!--<syntaxhighlight lang="phix">(phixonline)-->
say "Starting base $base...";
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
my @stems = grep { .is-prime }, ^$base;
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
for 1 .. * -> $digits {
<span style="color: #004080;">sequence</span> <span style="color: #000000;">tens</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
print ' ', @stems.elems;
<span style="color: #000000;">vals</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_inits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
my @new;
<span style="color: #000000;">digits</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
my $place = $base ** $digits;
<span style="color: #004080;">mpz</span> <span style="color: #000000;">answer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
for 1 ..^ $base -> $digit {
<span style="color: #004080;">integer</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">seen_depth</span>
my $left = $digit * $place;
for @stems -> $stem {
<span style="color: #008080;">procedure</span> <span style="color: #000000;">add_digit</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
my $new = $left + $stem;
<span style="color: #004080;">atom</span> <span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">1</span>
@new.push($new) if $new.is-prime;
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vals</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
}
<span style="color: #000000;">vals</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">mpz_init_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vals</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
}
<span style="color: #000000;">tens</span> <span style="color: #0000FF;">&=</span> <span style="color: #7060A8;">mpz_init_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
last unless @new;
<span style="color: #7060A8;">mpz_mul_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">tens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
@stems = @new;
<span style="color: #000000;">digits</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">0</span>
}
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
say "\nLargest ltp in base $base = { @stems.tail } or :$base\<{@stems.tail.base($base)}>\n";
<span style="color: #008080;">for</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
}</lang>
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">d</span>
<span style="color: #7060A8;">mpz_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vals</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">vals</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span>
<span style="color: #7060A8;">mpz_addmul_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vals</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">tens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">mpz_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vals</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #000000;">seen_depth</span>
<span style="color: #008080;">or</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">==</span><span style="color: #000000;">seen_depth</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">mpz_cmp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vals</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">answer</span><span style="color: #0000FF;">)></span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">mpz_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">answer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">vals</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
<span style="color: #000000;">seen_depth</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">add_digit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()></span><span style="color: #000000;">t1</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" base %d: (%d) %v \r"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">base</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">seen_depth</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">do_base</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">seen_depth</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #7060A8;">mpz_set_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">answer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">mpz_set_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tens</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">mpz_mul_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">tens</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">base</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">pi</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_prime</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">pi</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">base</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">mpz_set_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vals</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">pi</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">pi</span>
<span style="color: #000000;">add_digit</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">rd</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">answer</span><span style="color: #0000FF;">),</span>
<span style="color: #000000;">rb</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_get_str</span><span style="color: #0000FF;">(</span><span style="color: #000000;">answer</span><span style="color: #0000FF;">,</span><span style="color: #000000;">base</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">t</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">></span><span style="color: #000000;">0.1</span><span style="color: #0000FF;">?</span><span style="color: #008000;">" ["</span><span style="color: #0000FF;">&</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"]"</span><span style="color: #0000FF;">:</span><span style="color: #008000;">""</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%3d %-41s (%s, %d digits)%s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">base</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rd</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rb</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">rb</span><span style="color: #0000FF;">),</span><span style="color: #000000;">t</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">=</span><span style="color: #000000;">3</span> <span style="color: #008080;">to</span> <span style="color: #000000;">31</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #0000FF;">(</span><span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">or</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">12</span><span style="color: #0000FF;">,</span><span style="color: #000000;">14</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">21</span><span style="color: #0000FF;">,</span><span style="color: #000000;">25</span><span style="color: #0000FF;">,</span><span style="color: #000000;">27</span><span style="color: #0000FF;">,</span><span style="color: #000000;">31</span><span style="color: #0000FF;">}))</span>
<span style="color: #008080;">and</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">17</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">base</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">b</span>
<span style="color: #000000;">do_base</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">)</span>
<!--</syntaxhighlight>-->
{{out}}
Even (as in multiples of 2) bases above 18 omitted, so that it completes in a reasonable timeframe, although it does show progress.<br>
<pre>Starting base 3...
Likewise several further numbers are omitted under pwa/p2js so you can stare at a blank screen for about 6s instead of 4&frac12; mins.<br>
1 1 1
I once managed to get 18, but it took over 40 minutes, likewise 22 took 3 mins 46s, 33 over 8 mins, and 35 nearly 2 mins.
Largest ltp in base 3 = 23 or :3<212>
<pre>
 
3 23 (212, 3 digits)
Starting base 4...
4 4091 (333323, 6 digits)
2 2 3 3 3 3
5 7817 (222232, 6 digits)
Largest ltp in base 4 = 4091 or :4<333323>
6 4836525320399 (14141511414451435, 17 digits)
 
7 817337 (6642623, 7 digits)
Starting base 5...
8 14005650767869 (313636165537775, 15 digits)
2 4 4 3 1 1
9 1676456897 (4284484465, 10 digits)
Largest ltp in base 5 = 7817 or :5<222232>
10 357686312646216567629137 (357686312646216567629137, 24 digits) [0.2s]
 
11 2276005673 (a68822827, 9 digits)
Starting base 6...
12 13092430647736190817303130065827539 (471a34a164259ba16b324ab8a32b7817, 32 digits) [12.0s]
3 4 12 25 44 54 60 62 59 51 35 20 12 7 3 2 1
13 812751503 (cc4c8c65, 8 digits)
Largest ltp in base 6 = 4836525320399 or :6<14141511414451435>
14 615419590422100474355767356763 (d967ccd63388522619883a7d23, 26 digits) [2.3s]
 
15 34068645705927662447286191 (6c6c2ce2ceeea4826e642b, 22 digits) [0.6s]
Starting base 7...
16 1088303707153521644968345559987 (dbc7fba24fe6aec462abf63b3, 25 digits) [2.0s]
3 6 6 4 1 1 1
17 13563641583101 (6c66cc4cc83, 11 digits)
Largest ltp in base 7 = 817337 or :7<6642623>
19 546207129080421139 (cieg86gcea2c6h, 14 digits)
 
21 391461911766647707547123429659688417 (g8agg2gca8cak4k68gea4g2k22h, 27 digits) [5.8s]
Starting base 8...
23 116516557991412919458949 (immgm6c6imci66a4h, 17 digits)
4 12 29 50 66 77 61 51 38 27 17 8 3 2 1
25 8211352191239976819943978913 (me6om6oecgcc24c6eg6d, 20 digits) [1s]
Largest ltp in base 8 = 14005650767869 or :8<313636165537775>
27 10681632250257028944950166363832301357693 (o2akk6ekg844kaia4mack6c2ecab, 28 digits) [12.0s]
 
29 4300289072819254369986567661 (kcg66agsckeiasmckkj, 19 digits) [0.4s]
Starting base 9...
31 645157007060845985903112107793191 (uuauikuc4ui6oceci642sd, 22 digits) [1.3s]
4 9 15 17 24 16 9 6 5 3
"38s"
Largest ltp in base 9 = 1676456897 or :9<4284484465>
</pre>
 
Starting base 10...
4 11 39 99 192 326 429 521 545 517 448 354 276 212 117 72 42 24 13 6 5 4 3 1
Largest ltp in base 10 = 357686312646216567629137 or :10<357686312646216567629137>
 
Starting base 11...
4 8 15 18 15 8 4 2 1
Largest ltp in base 11 = 2276005673 or :11<A68822827>
 
Starting base 12...
5 23 119 409 1124 2496 4733 7711 11231 14826 17341 18787 19001 17567 15169 12085 9272 6606 4451 2882 1796 1108 601 346 181 103 49 19 8 2 1 1
Largest ltp in base 12 = 13092430647736190817303130065827539 or :12<471A34A164259BA16B324AB8A32B7817>
 
Starting base 13...
5 13 20 23 17 11 7 4
Largest ltp in base 13 = 812751503 or :13<CC4C8C65>
 
Starting base 14...
6 26 101 300 678 1299 2093 3017 3751 4196 4197 3823 3206 2549 1908 1269 783 507 322 163 97 55 27 13 5 2
Largest ltp in base 14 = 615419590422100474355767356763 or :14<D967CCD63388522619883A7D23>
 
Starting base 15...
6 22 79 207 391 644 934 1177 1275 1167 1039 816 608 424 261 142 74 45 25 13 7 1
Largest ltp in base 15 = 34068645705927662447286191 or :15<6C6C2CE2CEEEA4826E642B>
 
Starting base 16...
6 31 124 337 749 1292 1973 2695 3210 3490 3335 2980 2525 1840 1278 878 556 326 174 93 50 25 9 5 1
Largest ltp in base 16 = 1088303707153521644968345559987 or :16<DBC7FBA24FE6AEC462ABF63B3>
 
Starting base 17...
6 22 43 55 74 58 41 31 23 8 1
Largest ltp in base 17 = 13563641583101 or :17<6C66CC4CC83>
...</pre>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">import random
 
def is_probable_prime(n,k):
Line 1,254 ⟶ 1,735:
for b in range(3,24):
print("%d:%d\n" % (b,largest_left_truncatable_prime(b)))
</syntaxhighlight>
</lang>
 
Output:
Line 1,280 ⟶ 1,761:
</pre>
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">#lang racket
(require math/number-theory)
 
(define (prepend-digit b d i n)
(+ (* d (expt b i)) n))
 
(define (extend b i ts)
(define ts*
(for/list ([t (in-set ts)])
(for/set ([d (in-range 1 b)]
#:when (prime? (prepend-digit b d i t)))
(prepend-digit b d i t))))
(apply set-union ts*))
 
(define (truncables b n)
; return set of truncables of length n in base b
(if (= n 1)
(for/set ([d (in-range 1 b)] #:when (prime? d)) d)
(extend b (- n 1) (truncables b (- n 1)))))
 
(define (largest b)
(let loop ([ts (truncables b 1)]
[n 1])
(define ts* (extend b n ts))
(if (set-empty? ts*)
(apply max (set->list ts))
(loop ts* (+ n 1)))))
 
 
(for/list ([b (in-range 3 18)])
(define l (largest b))
; (displayln (list b l))
(list b l))
 
; Output:
'((3 23)
(4 4091)
(5 7817)
(6 4836525320399)
(7 817337)
(8 14005650767869)
(9 1676456897)
(10 357686312646216567629137)
(11 2276005673)
(12 13092430647736190817303130065827539)
(13 812751503)
(14 615419590422100474355767356763)
(15 34068645705927662447286191)
(16 1088303707153521644968345559987)
(17 13563641583101))</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.12}}
Pretty fast for bases 3 .. 11. 12 is slow. 18 is glacial.
<syntaxhighlight lang="raku" line>use ntheory:from<Perl5> <is_prime>;
 
for 3 .. 11 -> $base {
say "Starting base $base...";
my @stems = grep { .is-prime }, ^$base;
for 1 .. * -> $digits {
print ' ', @stems.elems;
my @new;
my $place = $base ** $digits;
for 1 ..^ $base -> $digit {
my $left = $digit * $place;
@new.append: (@stems »+» $left).grep: { is_prime("$_") }
}
last unless +@new;
@stems = @new;
}
say "\nLargest ltp in base $base = {@stems.max} or :$base\<@stems.max.base($base)}>\n";
}</syntaxhighlight>
{{out}}
<pre>Starting base 3...
1 1 1
Largest ltp in base 3 = 23 or :3<212>
 
Starting base 4...
2 2 3 3 3 3
Largest ltp in base 4 = 4091 or :4<333323>
 
Starting base 5...
2 4 4 3 1 1
Largest ltp in base 5 = 7817 or :5<222232>
 
Starting base 6...
3 4 12 25 44 54 60 62 59 51 35 20 12 7 3 2 1
Largest ltp in base 6 = 4836525320399 or :6<14141511414451435>
 
Starting base 7...
3 6 6 4 1 1 1
Largest ltp in base 7 = 817337 or :7<6642623>
 
Starting base 8...
4 12 29 50 66 77 61 51 38 27 17 8 3 2 1
Largest ltp in base 8 = 14005650767869 or :8<313636165537775>
 
Starting base 9...
4 9 15 17 24 16 9 6 5 3
Largest ltp in base 9 = 1676456897 or :9<4284484465>
 
Starting base 10...
4 11 39 99 192 326 429 521 545 517 448 354 276 212 117 72 42 24 13 6 5 4 3 1
Largest ltp in base 10 = 357686312646216567629137 or :10<357686312646216567629137>
 
Starting base 11...
4 8 15 18 15 8 4 2 1
Largest ltp in base 11 = 2276005673 or :11<A68822827>
 
Starting base 12...
5 23 119 409 1124 2496 4733 7711 11231 14826 17341 18787 19001 17567 15169 12085 9272 6606 4451 2882 1796 1108 601 346 181 103 49 19 8 2 1 1
Largest ltp in base 12 = 13092430647736190817303130065827539 or :12<471A34A164259BA16B324AB8A32B7817>
 
Starting base 13...
5 13 20 23 17 11 7 4
Largest ltp in base 13 = 812751503 or :13<CC4C8C65>
 
Starting base 14...
6 26 101 300 678 1299 2093 3017 3751 4196 4197 3823 3206 2549 1908 1269 783 507 322 163 97 55 27 13 5 2
Largest ltp in base 14 = 615419590422100474355767356763 or :14<D967CCD63388522619883A7D23>
 
Starting base 15...
6 22 79 207 391 644 934 1177 1275 1167 1039 816 608 424 261 142 74 45 25 13 7 1
Largest ltp in base 15 = 34068645705927662447286191 or :15<6C6C2CE2CEEEA4826E642B>
 
Starting base 16...
6 31 124 337 749 1292 1973 2695 3210 3490 3335 2980 2525 1840 1278 878 556 326 174 93 50 25 9 5 1
Largest ltp in base 16 = 1088303707153521644968345559987 or :16<DBC7FBA24FE6AEC462ABF63B3>
 
Starting base 17...
6 22 43 55 74 58 41 31 23 8 1
Largest ltp in base 17 = 13563641583101 or :17<6C66CC4CC83>
...</pre>
 
=={{header|Ruby}}==
===Ruby Ruby===
<langsyntaxhighlight lang="ruby">
# Compute the largest left truncatable prime
#
Line 1,306 ⟶ 1,922:
}
puts "The largest left truncatable prime #{"less than #{BASE ** MAX} " if MAX < 500}in base #{BASE} is #{stems.max}"
</syntaxhighlight>
</lang>
By changing BASE from 3 to 14 this produces the solutions in 'Number of left truncatable primes in a given base' on the Discussion Page for bases except 10, 12 and 14.
 
Line 1,316 ⟶ 1,932:
===JRuby===
I require a fast probably prime test. Java has one, is it any good? Let's find out. Ruby can borrow from Java using JRuby. Modifying the Ruby solution:
<syntaxhighlight lang="ruby">
<lang Ruby>
# Compute the largest left truncatable prime
#
Line 1,340 ⟶ 1,956:
}
puts "\nThe largest left truncatable prime #{"less than #{BASE ** MAX} " if MAX < 500}in base #{BASE} is #{stems.max}"
</syntaxhighlight>
</lang>
Produces all the reults in 'Number of left truncatable primes in a given base' on the discussion page. For bases 18, 20, and 22 I changed the confidence level from 100 to 5 and checked the final answer. Even so base 18 takes a while. For base 24:
<pre>
Line 1,350 ⟶ 1,966:
That is going to be big!
 
=={{header|RacketScala}}==
<syntaxhighlight lang="scala">import scala.collection.parallel.immutable.ParSeq
<lang racket>
#lang racket
(require math/number-theory)
 
object LeftTruncatablePrime extends App {
(define (prepend-digit b d i n)
private def leftTruncatablePrime(maxRadix: Int, millerRabinCertainty: Int) {
(+ (* d (expt b i)) n))
def getLargestLeftTruncatablePrime(radix: Int, millerRabinCertainty: Int): BigInt = {
def getNextLeftTruncatablePrimes(n: BigInt, radix: Int, millerRabinCertainty: Int) = {
def baseString = if (n == 0) "" else n.toString(radix)
 
for {i <- (1 until radix).par
(define (extend b i ts)
p = BigInt(Integer.toString(i, radix) + baseString, radix)
(define ts*
if p.isProbablePrime(millerRabinCertainty)
(for/list ([t (in-set ts)])
} yield (for/set ([d (in-range 1 b)]p
}
#:when (prime? (prepend-digit b d i t)))
(prepend-digit b d i t))))
(apply set-union ts*))
 
def iter(list: ParSeq[BigInt], lastList: ParSeq[BigInt]): ParSeq[BigInt] = {
(define (truncables b n)
if (list.isEmpty) lastList
; return set of truncables of length n in base b
(if (= n 1) else
iter((for (n <- list.par) yield getNextLeftTruncatablePrimes(n, radix, millerRabinCertainty)).flatten, list)
(for/set ([d (in-range 1 b)] #:when (prime? d)) d)
}
(extend b (- n 1) (truncables b (- n 1)))))
 
iter(getNextLeftTruncatablePrimes(0, radix, millerRabinCertainty), ParSeq.empty).max
(define (largest b)
}
(let loop ([ts (truncables b 1)]
[n 1])
(define ts* (extend b n ts))
(if (set-empty? ts*)
(apply max (set->list ts))
(loop ts* (+ n 1)))))
 
for (radix <- (3 to maxRadix).par) {
val largest = getLargestLeftTruncatablePrime(radix, millerRabinCertainty)
println(f"n=$radix%3d: " +
(if (largest == null) "No left-truncatable prime"
else f"$largest%35d (in base $radix%3d) ${largest.toString(radix)}"))
 
}
(for/list ([b (in-range 3 18)])
}
(define l (largest b))
; (displayln (list b l))
(list b l))
 
val argu: Array[String] = if (args.length >=2 ) args.slice(0, 2) else Array("17", "100")
; Output:
val maxRadix = argu(0).toInt.ensuring(_ > 2, "Radix must be an integer greater than 2.")
'((3 23)
 
(4 4091)
(5try 7817){
val millerRabinCertainty = argu(1).toInt
(6 4836525320399)
 
(7 817337)
println(s"Run with maxRadix = $maxRadix and millerRabinCertainty = $millerRabinCertainty")
(8 14005650767869)
 
(9 1676456897)
leftTruncatablePrime(maxRadix, millerRabinCertainty)
(10 357686312646216567629137)
println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
(11 2276005673)
}
(12 13092430647736190817303130065827539)
catch {
(13 812751503)
case _: NumberFormatException => Console.err.println("Miller-Rabin Certainty must be an integer.")
(14 615419590422100474355767356763)
}
(15 34068645705927662447286191)
 
(16 1088303707153521644968345559987)
}</syntaxhighlight>
(17 13563641583101))
</lang>
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">func primeslltp(n) {
var (i, j) = (0, 0)
gather {
loop {
i = j.next_prime
i <= n || break
take(j = i)
}
}
}
 
func lltp(n) {
var b = 1
var best = nil
var v = primes(n-1 -> primes)
 
while (v) {
Line 1,436 ⟶ 2,036:
for i in (3..17) {
printf("%2d %s\n", i, lltp(i))
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,455 ⟶ 2,055:
17 13563641583101
</pre>
 
Alternative solution:
<syntaxhighlight lang="ruby">func digits2num(digits, base) {
digits.map_kv {|k,v| base**k * v }.sum
}
 
func generate_from_suffix(p, base) {
 
var seq = [p]
 
for n in (1 ..^ base) {
var t = [p..., n]
if (is_prime(digits2num(t, base))) {
seq << __FUNC__(t, base)...
}
}
 
return seq
}
 
func left_truncatable_primes(base) {
 
var prime_digits = (base-1 -> primes)
 
prime_digits.map {|p| generate_from_suffix([p], base)... }\
.map {|t| digits2num(t, base) }\
.sort
}
 
for n in (3..11) {
var ltp = left_truncatable_primes(n)
say ("There are #{'%4d' % ltp.len} left-truncatable primes in base #{'%2d' % n}, where largest is #{ltp.max}")
}</syntaxhighlight>
{{out}}
<pre>
There are 3 left-truncatable primes in base 3, where largest is 23
There are 16 left-truncatable primes in base 4, where largest is 4091
There are 15 left-truncatable primes in base 5, where largest is 7817
There are 454 left-truncatable primes in base 6, where largest is 4836525320399
There are 22 left-truncatable primes in base 7, where largest is 817337
There are 446 left-truncatable primes in base 8, where largest is 14005650767869
There are 108 left-truncatable primes in base 9, where largest is 1676456897
There are 4260 left-truncatable primes in base 10, where largest is 357686312646216567629137
There are 75 left-truncatable primes in base 11, where largest is 2276005673
</pre>
 
=={{header|Swift}}==
{{trans|Python}}
{{libheader|Attaswift BigInt}}
<syntaxhighlight lang="text">import BigInt
 
func largestLeftTruncatablePrime(_ base: Int) -> BigInt {
var radix = 0
var candidates = [BigInt(0)]
 
while true {
let multiplier = BigInt(base).power(radix)
var newCandidates = [BigInt]()
 
for i in 1..<BigInt(base) {
newCandidates += candidates.map({ ($0+i*multiplier, ($0+i*multiplier).isPrime(rounds: 30)) })
.filter({ $0.1 })
.map({ $0.0 })
}
 
if newCandidates.count == 0 {
return candidates.max()!
}
 
candidates = newCandidates
radix += 1
}
}
 
for i in 3..<18 {
print("\(i): \(largestLeftTruncatablePrime(i))")
}</syntaxhighlight>
 
{{out}}
<pre>3: 23
4: 4091
5: 7817
6: 4836525320399
7: 817337
8: 14005650767869
9: 1676456897
10: 357686312646216567629137
11: 2276005673
12: 13092430647736190817303130065827539
13: 812751503
14: 615419590422100474355767356763
15: 34068645705927662447286191
16: 1088303707153521644968345559987
17: 13563641583101
 
real 1m17.433s
user 1m16.915s
sys 0m0.252s</pre>
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
 
proc tcl::mathfunc::modexp {a b n} {
Line 1,530 ⟶ 2,228:
for {set i 3} {$i <= 20} {incr i} {
puts "$i: [max_left_truncatable_prime $i]"
}</langsyntaxhighlight>
{{out|Output up to base 12 (tab-indented parts are progress messages)}}
<pre>
Line 1,619 ⟶ 2,317:
</pre>
I think I'll need to find a faster computer to calculate much more of the sequence, but memory consumption is currently negligible so there's no reason to expect there to be any major problems.
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-big}}
{{libheader|Wren-fmt}}
{{libheader|Wren-sort}}
{{libheader|Wren-ioutil}}
A tough task for the Wren interpreter which doesn't have the benefit of GMP.
 
A tad below 39 minutes to process up to base 17 at the lowest ''certainty'' level.
<syntaxhighlight lang="wren">import "./big" for BigInt
import "./fmt" for Conv, Fmt
import "./sort" for Sort
import "./ioutil" for Input
 
var nextLeftTruncatablePrimes = Fn.new { |n, radix, certainty|
var probablePrimes = []
var baseString = (n == BigInt.zero) ? "" : n.toBaseString(radix)
for (i in 1...radix) {
var p = BigInt.fromBaseString(Conv.itoa(i, radix) + baseString, radix)
if (p.isProbablePrime(certainty)) probablePrimes.add(p)
}
return probablePrimes
}
 
var largestLeftTruncatablePrime = Fn.new { |radix, certainty|
var lastList = null
var list = nextLeftTruncatablePrimes.call(BigInt.zero, radix, certainty)
while (!list.isEmpty) {
lastList = list
list = []
for (n in lastList) list.addAll(nextLeftTruncatablePrimes.call(n, radix, certainty))
}
if (!lastList) return null
Sort.quick(lastList)
return lastList[-1]
}
 
var maxRadix = Input.integer("Enter maximum radix : ", 3, 36)
var certainty = Input.integer("Enter certainty : ", 1, 100)
System.print()
for (radix in 3..maxRadix) {
var largest = largestLeftTruncatablePrime.call(radix, certainty)
Fmt.write("Base = $-2d : ", radix)
if (!largest) {
System.print("No left truncatable prime")
} else {
Fmt.print("$-35i -> $s", largest, largest.toBaseString(radix))
}
}</syntaxhighlight>
 
{{out}}
<pre>
Enter maximum radix : 17
Enter certainty : 1
 
Base = 3 : 23 -> 212
Base = 4 : 4091 -> 333323
Base = 5 : 7817 -> 222232
Base = 6 : 4836525320399 -> 14141511414451435
Base = 7 : 817337 -> 6642623
Base = 8 : 14005650767869 -> 313636165537775
Base = 9 : 1676456897 -> 4284484465
Base = 10 : 833757579699383379513367 -> 833757579699383379513367
Base = 11 : 2276005673 -> a68822827
Base = 12 : 13092430647736190817303130065827539 -> 471a34a164259ba16b324ab8a32b7817
Base = 13 : 812751503 -> cc4c8c65
Base = 14 : 615419590422100474355767356763 -> d967ccd63388522619883a7d23
Base = 15 : 34068645705927662447286191 -> 6c6c2ce2ceeea4826e642b
Base = 16 : 1088303707153521644968345559987 -> dbc7fba24fe6aec462abf63b3
Base = 17 : 13563641583101 -> 6c66cc4cc83
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">var [const] BN=Import("zklBigNum"); // libGMP
fcn largest_lefty_prime(base){
primes,p:=List(),BN(1); while(p.nextPrime()<base){ primes.append(p.copy()) }
Line 1,639 ⟶ 2,409:
}
 
foreach n in ([3..17]){ println("%2d %s".fmt(n,largest_lefty_prime(n))) }</langsyntaxhighlight>
I've included 18,19 & 20 here but 18 & 20 are very very slow to compute, it is seconds to compute all the others.
{{out}}
9,476

edits