Ormiston pairs: Difference between revisions

→‎{{header|Free Pascal}}: checking mod 18 =0 is faster.
m (uups sort entries)
(→‎{{header|Free Pascal}}: checking mod 18 =0 is faster.)
Line 412:
=={{header|Pascal}}==
==={{header|Free Pascal}}===
//update the digits by adding difference.// Using MOD 18 = 0 and convert is faster.
<syntaxhighlight lang=pascal>
program Ormiston;
Line 533:
 
type
td10_UsedDgtstDigits10 = array[0..1115] of byte;
td10_UsedDgts2 = array[0..23] of Uint32;
tpd10_UsedDgts2 = ^td10_UsedDgts2;
//size of 32 byte. two XMMx - 16 byte copies p1:=p2
tDigits10 = record
d10_UsedDgts :td10_UsedDgts;
d10_dgts :array[0..15] of byte;
d10_maxIdx : Uint32;
end;
 
procedure Out_Digits10(const p0:tDigits10);
var
p_zero : tDigits10;// faster than fillchar
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);
Line 575 ⟶ 552:
end;
 
functionprocedure Convert2Digits10(p:Uint32)NativeUint;var outP:tDigits10);
var
i,r,m10 : Uint32NativeUint;
begin
ioutP := 0p_zero;
fillchar(result,SizeOf(result),#0);
with result do
begin
i := 0;
repeat
r := p DIV 10;
m10 := inc(outP[p-10*r]);
d10_dgts[i] := m10;
inc(d10_UsedDgts[m10]);
inc(i);
p := r;
until r = 0;
Line 594 ⟶ 566:
end;
 
function CheckOrmiston(const d1,d2:tpd10_UsedDgts2):boolean;inline;
procedure Add2Digits10(delta:Uint32;var p0,p1:tDigits10);
// checking four digits at once.Ord to circumvent conditional jumps
var
i,r,m10,dgt: Uint32;
begin
p1 := p0;
with p1 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;
 
function CheckOrmiston(d1,d2:tpd10_UsedDgts2):boolean;inline;
//check 4 byte at once, not byte by byte
begin
result := exit((ORD(d1^[0]=d2^[0]) AND+ ORD(d1^[1]=d2^[1]) AND+ ORD(d1^[2]=d2^[2])) =3);
// result := (d1^[0]=d2^[0]) AND (d1^[1]=d2^[1]) AND (d1^[2]=d2^[2]);
end;
 
Line 639 ⟶ 576:
pSieve : tpPrimes;
T1,T0: TDateTime;
{$align 16}
p1,p2 :tDigits10;
pr,pr_before,
Line 650 ⟶ 588:
pSieve := @PrimeSieve[0];
pr_before := 2;
p1 := Convert2Digits10(pr_before,p1);
pr := pr_before;
prLimit := 100*1000;
Line 660 ⟶ 598:
if pr > limit then
BREAK;
Add2Digits10if (pr-pr_before,p1,p2); mod 18 = 0 then
if CheckOrmiston(@p1.d10_UsedDgts,@p2.d10_UsedDgts) then
begin
incConvert2Digits10(cntpr,p1);
Convert2Digits10(pr_before,p2);
IF cnt <= 30 then
if OutInCheckOrmiston(cnt@p1,pr_before,pr@p2); then
begin
dec inc(icnt);
if dgt >IF cnt <= 1030 then
OutIn(cnt,pr_before,pr);
end;
end;
p1 := p2;
Line 688 ⟶ 630:
34,901 Ormiston pairs before 100,000,000
 
Real time: 0.824648 s User time: 0.717557 s Sys. time: 0.100085 s CPU share: 99.0805 %
 
@home 1E10
// Limit= 10*1000*1000*1000;
time for sieving 00:17.926708
....
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 0m300m25,479s887s user 0m28,191s sys 0m23,680s sys 0m2,279s199s
</pre>
 
=={{header|Phix}}==
{{trans|Wren}}
132

edits