Multi-base primes: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: prepend pascal) |
(→{{header|Pascal}}: inserted pascal version) |
||
Line 419: | Line 419: | ||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
First counting the bases that convert a decimal string of n into a prime number.<BR> |
|||
Afterwards only checking the maxcount for the used bases.<BR> |
|||
Most time consuming is sieving for the primes. |
|||
<lang pascal>program DecStringIsPrimeInBase; |
|||
//base 10 numeric string |
|||
{$IFDEF FPC} |
|||
{$MODE DELPHI} |
|||
{$OPTIMIZATION ON,ALL} |
|||
{$CodeAlign proc=32,loop=1} |
|||
{$ELSE} |
|||
{$APPTYPE CONSOLE} |
|||
{$ENDIF} |
|||
uses |
|||
sysutils; |
|||
const |
|||
MINBASE = 2; |
|||
MAXBASE = 36; |
|||
MAXFACPOT = 6; |
|||
MAXFAC = 10*10*10*10*10*10; |
|||
type |
|||
tChkLst = array of byte; |
|||
tSol = array of Uint32; |
|||
//sieve primes see http://rosettacode.org/wiki/Sieve_of_Eratosthenes#alternative_using_wheel |
|||
var |
|||
BoolPrimes: array of boolean; |
|||
ChkLst :tChkLst; |
|||
function popcnt64(n:Uint64):integer; |
|||
begin |
|||
result := 0; |
|||
repeat |
|||
result += ORD(n AND 1 <> 0); |
|||
n := n shr 1; |
|||
until n = 0; |
|||
end; |
|||
function BuildWheel(primeLimit:Int32):NativeUint; |
|||
var |
|||
myPrimes : pBoolean; |
|||
wheelprimes :array[0..31] of byte; |
|||
wheelSize,wpno, |
|||
pr,pw,i, k: NativeUint; |
|||
begin |
|||
myPrimes := @BoolPrimes[0]; |
|||
pr := 1; |
|||
myPrimes[1]:= true; |
|||
WheelSize := 1; |
|||
wpno := 0; |
|||
repeat |
|||
inc(pr); |
|||
pw := pr; |
|||
if pw > wheelsize then |
|||
dec(pw,wheelsize); |
|||
If myPrimes[pw] then |
|||
begin |
|||
k := WheelSize+1; |
|||
for i := 1 to pr-1 do |
|||
begin |
|||
inc(k,WheelSize); |
|||
if k<primeLimit then |
|||
move(myPrimes[1],myPrimes[k-WheelSize],WheelSize) |
|||
else |
|||
begin |
|||
move(myPrimes[1],myPrimes[k-WheelSize],PrimeLimit-WheelSize*i); |
|||
break; |
|||
end; |
|||
end; |
|||
dec(k); |
|||
IF k > primeLimit then |
|||
k := primeLimit; |
|||
wheelPrimes[wpno] := pr; |
|||
myPrimes[pr] := false; |
|||
inc(wpno); |
|||
WheelSize := k; |
|||
i:= pr; |
|||
i := i*i; |
|||
while i <= k do |
|||
begin |
|||
myPrimes[i] := false; |
|||
inc(i,pr); |
|||
end; |
|||
end; |
|||
until WheelSize >= PrimeLimit; |
|||
while wpno > 0 do |
|||
begin |
|||
dec(wpno); |
|||
myPrimes[wheelPrimes[wpno]] := true; |
|||
end; |
|||
myPrimes[0] := false; |
|||
myPrimes[1] := false; |
|||
BuildWheel := pr+1; |
|||
writeln; |
|||
end; |
|||
procedure Sieve(PrimeLimit:Int32); |
|||
var |
|||
myPrimes : pBoolean; |
|||
sieveprime, |
|||
fakt : NativeUint; |
|||
begin |
|||
setlength(BoolPrimes,PrimeLimit+1); |
|||
myPrimes := @BoolPrimes[0]; |
|||
sieveprime := BuildWheel(PrimeLimit); |
|||
repeat |
|||
if myPrimes[sieveprime] then |
|||
begin |
|||
fakt := PrimeLimit DIV sieveprime; |
|||
IF fakt < sieveprime then |
|||
BREAK; |
|||
repeat |
|||
myPrimes[sieveprime*fakt] := false; |
|||
repeat |
|||
dec(fakt); |
|||
until myPrimes[fakt]; |
|||
until fakt < sieveprime; |
|||
end; |
|||
inc(sieveprime); |
|||
until false; |
|||
myPrimes[1] := false; |
|||
end; |
|||
function CnvtoBase(n,base:Uint32):Uint32; |
|||
//with test of digit >= base |
|||
var |
|||
q,r,fac: Uint32; |
|||
Begin |
|||
fac := 1; |
|||
result := 0; |
|||
repeat |
|||
q := n DIV 10; |
|||
r := (n-q*10); |
|||
if r >= base then |
|||
break; |
|||
result += fac*r; |
|||
fac *= base; |
|||
n := q; |
|||
until (n = 0); |
|||
if r >= base then |
|||
result := 0; |
|||
end; |
|||
function CnvtoBase11toMAXBASE(n,base:Uint32):Uint32; |
|||
var |
|||
q,r,fac: Uint32; |
|||
Begin |
|||
fac := 1; |
|||
result := 0; |
|||
repeat |
|||
q := n DIV 10; |
|||
r := (n-q*10); |
|||
result += fac*r; |
|||
fac *= Base; |
|||
n := q; |
|||
until n = 0; |
|||
end; |
|||
procedure ConvertToBases(n:Uint32); |
|||
var |
|||
base,r,Counter: Uint32; |
|||
begin |
|||
Counter := 0; |
|||
//base 10 |
|||
if boolprimes[n] then |
|||
inc(Counter); |
|||
for base := MINBASE TO 9 do |
|||
Begin |
|||
r := CnvtoBase(n,base); |
|||
// if boolprimes[r] then inc(Counter); |
|||
inc(Counter,Ord(boolprimes[r])); |
|||
end; |
|||
for base := 11 TO MAXBASE do |
|||
Begin |
|||
r := CnvtoBase11toMAXBASE(n,base); |
|||
// if boolprimes[r] then inc(Counter); |
|||
inc(Counter,Ord(boolprimes[r])); |
|||
end; |
|||
chklst[n] := Counter; |
|||
end; |
|||
function GetMax(MinLmt,MaxLmt:Uint32):tSol; |
|||
var |
|||
i,pc,max,Idx: Int32; |
|||
Begin |
|||
setlength(result,10); |
|||
max :=-1; |
|||
Idx:= 0; |
|||
For i := MinLmt to MaxLmt do |
|||
Begin |
|||
pc := ChkLst[i]; |
|||
if max<=pc then |
|||
begin |
|||
if max = pc then |
|||
begin |
|||
inc(Idx); |
|||
if Idx > High(result) then |
|||
setlength(result,Idx+10); |
|||
result[idx-1] := i; |
|||
end |
|||
else |
|||
begin |
|||
Idx:= 1; |
|||
result[Idx-1] := i; |
|||
max := pc; |
|||
end; |
|||
end; |
|||
end; |
|||
setlength(result,idx); |
|||
end; |
|||
procedure Out_Sol(sol:tSol); |
|||
var |
|||
sl : string[8]; |
|||
s : AnsiString; |
|||
i,n,base,r,cnt: Uint32; |
|||
begin |
|||
if length(Sol) = 0 then |
|||
EXIT; |
|||
cnt := 0; |
|||
for i := 0 to High(Sol) do |
|||
begin |
|||
n := sol[i]; |
|||
str(n:7,sl); |
|||
s := sl+' -> ['; |
|||
For base := MINBASE to MAXBASE do |
|||
Begin |
|||
r := CnvtoBase(n,base); |
|||
if boolprimes[r] then |
|||
begin |
|||
inc(cnt); |
|||
str(base,sl); |
|||
s := s+sl+','; |
|||
end; |
|||
end; |
|||
s[length(s)] := ']'; |
|||
if i = 0 then |
|||
writeln(cnt); |
|||
writeln(s); |
|||
end; |
|||
writeln; |
|||
setlength(Sol,0); |
|||
end; |
|||
var |
|||
T0 : Int64; |
|||
i,lmt,minLmt : Uint32; |
|||
begin |
|||
T0 := GetTickCount64; |
|||
lmt := 0; |
|||
//maxvalue of "99...99" in Maxbase |
|||
for i := 1 to MAXFACPOT do |
|||
lmt := (lmt*MAXBASE+9); |
|||
writeln('max prime limit ',lmt); |
|||
Sieve(lmt); |
|||
Setlength(ChkLst,MAXFAC); |
|||
writeln('Start ',(GetTickCount64-T0)/1000:6:3,' s'); |
|||
For i := 2 to MAXFAC-1 do |
|||
ConvertToBases(i); |
|||
i := 1; |
|||
minLmt := 1; |
|||
repeat |
|||
write(i:2,' character strings which are prime in most bases: '); |
|||
Out_Sol(GetMax(minLmt,10*minLmt-1)); |
|||
minLmt *= 10; |
|||
inc(i); |
|||
until minLmt >= MAXFAC; |
|||
{$IFDEF WINDOWS} readln; {$ENDIF} |
|||
end.</lang> |
|||
{{out}} |
|||
<pre> |
|||
TIO.RUN |
|||
max prime limit 559744029 |
|||
Start 2.343 s |
|||
1 character strings which are prime in most bases: 34 |
|||
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] |
|||
2 character strings which are prime in most bases: 18 |
|||
21 -> [3,5,6,8,9,11,14,15,18,20,21,23,26,29,30,33,35,36] |
|||
3 character strings which are prime in most bases: 18 |
|||
131 -> [4,5,7,8,9,10,12,14,15,18,19,20,23,25,27,29,30,34] |
|||
551 -> [6,7,11,13,14,15,16,17,19,21,22,24,25,26,30,32,35,36] |
|||
737 -> [8,9,11,12,13,15,16,17,19,22,23,24,25,26,29,30,31,36] |
|||
4 character strings which are prime in most bases: 19 |
|||
1727 -> [8,9,11,12,13,15,16,17,19,20,22,23,24,26,27,29,31,33,36] |
|||
5347 -> [8,9,10,11,12,13,16,18,19,22,24,25,26,30,31,32,33,34,36] |
|||
5 character strings which are prime in most bases: 18 |
|||
30271 -> [8,10,12,13,16,17,18,20,21,23,24,25,31,32,33,34,35,36] |
|||
6 character strings which are prime in most bases: 18 |
|||
441431 -> [5,8,9,11,12,14,16,17,19,21,22,23,26,28,30,31,32,33] |
|||
Real time: 3.047 s CPU share: 97.07 % |
|||
//Start 1.077 s real 0m1,364s at home</pre> |
|||
=={{header|Phix}}== |
=={{header|Phix}}== |