Ormiston pairs: Difference between revisions
Content added Content deleted
m (→{{header|jq}}: tidy) |
(→{{header|jq}}: prepend Free Pascal version) |
||
Line 342: | Line 342: | ||
+/isorm i.&.(p:inv) 1e7 NB. number of Ormiston pairs less than 1e7 |
+/isorm i.&.(p:inv) 1e7 NB. number of Ormiston pairs less than 1e7 |
||
3722</syntaxhighlight> |
3722</syntaxhighlight> |
||
=={{header|Pascal}}== |
|||
==={{header|Free Pascal}}=== |
|||
update the digits by adding difference. |
|||
<syntaxhighlight lang=jq> |
|||
program Ormiston; |
|||
{$IFDEF FPC}{$MODE DELPHI} {$OPTIMIZATION ON,ALL}{$ENDIF} |
|||
{$IFDEF WINDOWS}{$APPLICATION CONSOLE}{$ENDIF} |
|||
uses |
|||
sysutils,strUtils; |
|||
const |
|||
Limit= 100*1000*1000; |
|||
type |
|||
tPrimesSieve = array of boolean; |
|||
tpPrimes = pBoolean; |
|||
var |
|||
PrimeSieve : tPrimesSieve; |
|||
//*********** Sieve of erathostenes |
|||
procedure ClearAll; |
|||
begin |
|||
setlength(PrimeSieve,0); |
|||
end; |
|||
function BuildWheel(pPrimes:tpPrimes;lmt:Uint64): Uint64; |
|||
var |
|||
wheelSize, wpno, pr, pw, i, k: NativeUint; |
|||
wheelprimes: array[0..15] of byte; |
|||
begin |
|||
pr := 1;//the mother of all numbers 1 ;-) |
|||
pPrimes[1] := True; |
|||
WheelSize := 1; |
|||
wpno := 0; |
|||
repeat |
|||
Inc(pr); |
|||
//pw = pr projected in wheel of wheelsize |
|||
pw := pr; |
|||
if pw > wheelsize then |
|||
Dec(pw, wheelsize); |
|||
if pPrimes[pw] then |
|||
begin |
|||
k := WheelSize + 1; |
|||
//turn the wheel (pr-1)-times |
|||
for i := 1 to pr - 1 do |
|||
begin |
|||
Inc(k, WheelSize); |
|||
if k < lmt then |
|||
move(pPrimes[1], pPrimes[k - WheelSize], WheelSize) |
|||
else |
|||
begin |
|||
move(pPrimes[1], pPrimes[k - WheelSize], Lmt - WheelSize * i); |
|||
break; |
|||
end; |
|||
end; |
|||
Dec(k); |
|||
if k > lmt then |
|||
k := lmt; |
|||
wheelPrimes[wpno] := pr; |
|||
pPrimes[pr] := False; |
|||
Inc(wpno); |
|||
WheelSize := k;//the new wheelsize |
|||
//sieve multiples of the new found prime |
|||
i := pr; |
|||
i := i * i; |
|||
while i <= k do |
|||
begin |
|||
pPrimes[i] := False; |
|||
Inc(i, pr); |
|||
end; |
|||
end; |
|||
until WheelSize >= lmt; |
|||
//re-insert wheel-primes 1 still stays prime |
|||
while wpno > 0 do |
|||
begin |
|||
Dec(wpno); |
|||
pPrimes[wheelPrimes[wpno]] := True; |
|||
end; |
|||
result := pr; |
|||
end; |
|||
procedure Sieve(pPrimes:tpPrimes;lmt:Uint64); |
|||
var |
|||
sieveprime, fakt, i: UInt64; |
|||
begin |
|||
sieveprime := BuildWheel(pPrimes,lmt); |
|||
repeat |
|||
repeat |
|||
Inc(sieveprime); |
|||
until pPrimes[sieveprime]; |
|||
fakt := Lmt div sieveprime; |
|||
while Not(pPrimes[fakt]) do |
|||
dec(fakt); |
|||
if fakt < sieveprime then |
|||
BREAK; |
|||
i := (fakt + 1) mod 6; |
|||
if i = 0 then |
|||
i := 4; |
|||
repeat |
|||
pPrimes[sieveprime * fakt] := False; |
|||
repeat |
|||
Dec(fakt, i); |
|||
i := 6 - i; |
|||
until (fakt < sieveprime) OR pPrimes[fakt]; |
|||
if fakt < sieveprime then |
|||
BREAK; |
|||
until False; |
|||
until False; |
|||
pPrimes[1] := False;//remove 1 |
|||
end; |
|||
procedure InitAndGetPrimes; |
|||
begin |
|||
setlength(PrimeSieve,Limit+2); |
|||
Sieve(@PrimeSieve[0],Limit); |
|||
PrimeSieve[Limit+1] := true; |
|||
end; |
|||
//*********** End Sieve of erathostenes |
|||
type |
|||
tDigits10 = record |
|||
d10_UsedDgts : array[0..11] of byte; |
|||
d10_dgts :array[0..15] of byte; |
|||
d10_maxIdx : Uint32; |
|||
end; |
|||
procedure Out_Digits10(const p0:tDigits10); |
|||
var |
|||
i : Int32; |
|||
begin |
|||
with p0 do |
|||
begin |
|||
i := d10_maxIdx; |
|||
while i >= 0 do |
|||
begin |
|||
write(d10_dgts[i]); |
|||
dec(i); |
|||
end; |
|||
write(' '); |
|||
For i := 0 to 9 do |
|||
write(d10_UsedDgts[i]); |
|||
writeln; |
|||
end; |
|||
end; |
|||
procedure OutIn(cnt,p1,p2:NativeInt); |
|||
Begin |
|||
write('[',Numb2USA(IntToStr(p1)):6,'|',Numb2USA(IntToStr(p2)):6,']'); |
|||
if cnt MOD 5 = 0 then |
|||
writeln; |
|||
end; |
|||
function OutByPot10(cnt,prLimit:NativeInt):NativeInt; |
|||
Begin |
|||
writeln(Numb2USA(IntToStr(cnt)):12,' Ormiston pairs before ',Numb2USA(IntToStr(prLimit)):14); |
|||
result := 10*prLimit; |
|||
end; |
|||
function Convert2Digits10(p:Uint32):tDigits10; |
|||
var |
|||
i,r,m10: Uint32; |
|||
begin |
|||
fillchar(result,SizeOf(result),#0); |
|||
with result do |
|||
begin |
|||
i := 0; |
|||
repeat |
|||
r := p DIV 10; |
|||
m10 := p-10*r; |
|||
d10_dgts[i] := m10; |
|||
inc(d10_UsedDgts[m10]); |
|||
inc(i); |
|||
p := r; |
|||
until r = 0; |
|||
end; |
|||
end; |
|||
function Add2Digits10(delta:Uint32;const p0:tDigits10):tDigits10; |
|||
var |
|||
i,r,m10,dgt: Uint32; |
|||
begin |
|||
result := p0; |
|||
with result do |
|||
begin |
|||
i := 0; |
|||
repeat |
|||
m10 := d10_dgts[i]; |
|||
//remove old digit |
|||
dec(d10_UsedDgts[m10]); |
|||
r := delta DIV 10; |
|||
dgt := m10 + delta -10*r; |
|||
if dgt >= 10 then |
|||
begin |
|||
dgt -= 10; |
|||
r += 1; |
|||
end; |
|||
d10_dgts[i] := dgt; |
|||
//insert new digit |
|||
inc(d10_UsedDgts[dgt]); |
|||
delta := r; |
|||
inc(i); |
|||
until (i> d10_maxIdx) OR (delta = 0); |
|||
if (i> d10_maxIdx) AND (delta>0) then |
|||
begin |
|||
d10_maxIdx += 1; |
|||
r := delta DIV 10; |
|||
dgt := delta -10*r; |
|||
d10_dgts[i] := dgt; |
|||
inc(d10_UsedDgts[dgt]); |
|||
end; |
|||
end; |
|||
end; |
|||
var |
|||
pSieve : tpPrimes; |
|||
T1,T0: TDateTime; |
|||
p1,p2 :tDigits10; |
|||
pr,pr_before, |
|||
i,cnt,prLimit :nativeInt; |
|||
Begin |
|||
T0 := now; |
|||
InitAndGetPrimes; |
|||
T1 := now; |
|||
Writeln('time for sieving ',FormatDateTime('NN:SS.ZZZ',T1-T0)); |
|||
pSieve := @PrimeSieve[0]; |
|||
pr_before := 2; |
|||
p1 := Convert2Digits10(pr_before); |
|||
pr := pr_before; |
|||
prLimit := 100*1000; |
|||
cnt := 0; |
|||
repeat |
|||
repeat |
|||
inc(pr); |
|||
until pSieve[pr];// pr[limit+1] set to true |
|||
if pr > limit then |
|||
BREAK; |
|||
p2 := Add2Digits10(pr-pr_before,p1); |
|||
i := 9; |
|||
repeat |
|||
if p2.d10_UsedDgts[i] <> p1.d10_UsedDgts[i] then |
|||
BREAK; |
|||
dec(i); |
|||
until i < 0; |
|||
if i < 0 then |
|||
begin |
|||
inc(cnt); |
|||
IF cnt <= 30 then |
|||
OutIn(cnt,pr_before,pr); |
|||
// Out_Digits10(p1); write(pr:10,' ');Out_Digits10(p2); |
|||
end; |
|||
p1 := p2; |
|||
pr_before := pr; |
|||
if pr >=prLimit then |
|||
prlimit:= OutByPot10(cnt,prlimit); |
|||
until false; |
|||
OutByPot10(cnt,prlimit); |
|||
end.</syntaxhighlight> |
|||
{{out|@TIO.RUN}} |
|||
<pre> |
|||
time for sieving 00:00.333 |
|||
[ 1,913| 1,931][18,379|18,397][19,013|19,031][25,013|25,031][34,613|34,631] |
|||
[35,617|35,671][35,879|35,897][36,979|36,997][37,379|37,397][37,813|37,831] |
|||
[40,013|40,031][40,213|40,231][40,639|40,693][45,613|45,631][48,091|48,109] |
|||
[49,279|49,297][51,613|51,631][55,313|55,331][56,179|56,197][56,713|56,731] |
|||
[58,613|58,631][63,079|63,097][63,179|63,197][64,091|64,109][65,479|65,497] |
|||
[66,413|66,431][74,779|74,797][75,913|75,931][76,213|76,231][76,579|76,597] |
|||
40 Ormiston pairs before 100,000 |
|||
382 Ormiston pairs before 1,000,000 |
|||
3,722 Ormiston pairs before 10,000,000 |
|||
34,901 Ormiston pairs before 100,000,000 |
|||
Real time: 0.986 s User time: 0.866 s Sys. time: 0.106 s CPU share: 98.64 % |
|||
@home 1E10 |
|||
time for sieving 00:17.926 |
|||
... |
|||
34,901 Ormiston pairs before 100,000,000 |
|||
326,926 Ormiston pairs before 1,000,000,000 |
|||
3,037,903 Ormiston pairs before 10,000,000,000 |
|||
real 0m30,479s user 0m28,191s sys 0m2,279s |
|||
</pre> |
|||
=={{header|jq}}== |
=={{header|jq}}== |