Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
212
Task/Unprimeable-numbers/Pascal/unprimeable-numbers-1.pas
Normal file
212
Task/Unprimeable-numbers/Pascal/unprimeable-numbers-1.pas
Normal file
|
|
@ -0,0 +1,212 @@
|
|||
program unprimable;
|
||||
{$IFDEF FPC}{$Mode Delphi}{$ELSE}{$APPTYPE CONSOLE}{$ENDIF}
|
||||
|
||||
const
|
||||
base = 10;
|
||||
|
||||
type
|
||||
TNumVal = array[0..base-1] of NativeUint;
|
||||
TConvNum = record
|
||||
NumRest : TNumVal;
|
||||
LowDgt,
|
||||
MaxIdx : NativeUint;
|
||||
end;
|
||||
|
||||
var //global
|
||||
PotBase,
|
||||
EndDgtFound : TNumVal;
|
||||
TotalCnt,
|
||||
EndDgtCnt :NativeUint;
|
||||
|
||||
procedure Init;
|
||||
var
|
||||
i,val : NativeUint;
|
||||
Begin
|
||||
val := 1;
|
||||
For i := low(TNumVal) to High(TNumVal) do
|
||||
Begin
|
||||
EndDgtFound[i] :=0;
|
||||
PotBase[i] := val;
|
||||
val := val * Base;
|
||||
end;
|
||||
TotalCnt := 0;
|
||||
EndDgtCnt := 0;
|
||||
end;
|
||||
|
||||
Procedure ConvertNum(n: NativeUint;var NConv:TConvNum);
|
||||
//extract digit position replace by "0" to get NumRest
|
||||
// 173 -> 170 -> 103 -> 073
|
||||
var
|
||||
i, dgt,n_red,n_mod: NativeUint;
|
||||
begin
|
||||
i := 0;
|
||||
n_red := n;
|
||||
with NConv do
|
||||
Begin
|
||||
repeat
|
||||
n_mod := n_red DIV Base;
|
||||
dgt := n_red-Base*n_mod;
|
||||
n_red := n_mod;
|
||||
IF i = 0 then
|
||||
LowDgt := dgt;
|
||||
NumRest[i]:= n-dgt*PotBase[i];
|
||||
inc(i);
|
||||
until (i > High(TNumVal)) OR (n<PotBase[i]);
|
||||
MaxIdx := i-1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure CheckOutPut(n: NativeUint);
|
||||
Begin
|
||||
IF TotalCnt > 600 then
|
||||
EXIT;
|
||||
IF TotalCnt <= 35 then
|
||||
write(n,' ');
|
||||
IF TotalCnt = 600 then
|
||||
Begin
|
||||
writeln;
|
||||
writeln;
|
||||
writeln('the 600.th unprimable number: ',n);
|
||||
end;
|
||||
end;
|
||||
|
||||
function isPrime(n : NativeUint):boolean;inline;
|
||||
var
|
||||
p : NativeUint;
|
||||
Begin
|
||||
result := (N=2) OR (N=3);
|
||||
IF result then
|
||||
EXIT;
|
||||
//now result = false
|
||||
IF (n<2) OR (NOT(ODD(n))) or (n mod 3= 0) then
|
||||
EXIT;
|
||||
p := 5;
|
||||
while p*p <= n do
|
||||
Begin
|
||||
if n mod p = 0 then
|
||||
Exit;
|
||||
inc(p,2);
|
||||
if n mod p = 0 then
|
||||
Exit;
|
||||
inc(p,4);
|
||||
end;
|
||||
result := true;
|
||||
end;
|
||||
|
||||
procedure InsertFound(LowDgt,n:NativeUInt);
|
||||
Begin
|
||||
inc(TotalCnt);
|
||||
IF EndDgtFound[LowDgt] = 0 then
|
||||
Begin
|
||||
EndDgtFound[LowDgt] := n;
|
||||
inc(EndDgtCnt);
|
||||
end;
|
||||
end;
|
||||
|
||||
function CheckUnprimable(n:NativeInt):boolean;
|
||||
var
|
||||
ConvNum : TConvNum;
|
||||
val,dgt,i,dtfac: NativeUint;
|
||||
Begin
|
||||
ConvertNum(n,ConvNum);
|
||||
result := false;
|
||||
//lowest digit
|
||||
with ConvNum do
|
||||
Begin
|
||||
val := NumRest[0];
|
||||
For dgt := 0 to Base-1 do
|
||||
IF isPrime(val+dgt) then
|
||||
EXIT;
|
||||
dgt := LowDgt;
|
||||
|
||||
result := true;
|
||||
i := MaxIdx;
|
||||
IF NumRest[i] >= Base then
|
||||
Begin
|
||||
//****Only for base=10 if even or divisible by 5***
|
||||
IF Not(ODD(dgt)) OR (dgt=5) then
|
||||
Begin
|
||||
InsertFound(dgt,n);
|
||||
EXIT;
|
||||
end;
|
||||
end;
|
||||
|
||||
result := false;
|
||||
For i := MaxIdx downto 1 do
|
||||
Begin
|
||||
dtfac := PotBase[i];
|
||||
val := NumRest[i];
|
||||
For dgt := 0 to Base-1 do
|
||||
Begin
|
||||
IF isPrime(val) then
|
||||
EXIT;
|
||||
inc(val,dtfac);
|
||||
end;
|
||||
end;
|
||||
InsertFound(LowDgt,n);
|
||||
result := true;
|
||||
end;
|
||||
end;
|
||||
|
||||
function CheckUnprimableReduced(n:NativeInt):boolean;
|
||||
//lowest digit already tested before
|
||||
var
|
||||
ConvNum : TConvNum;
|
||||
val,dgt,i,dtfac: NativeUint;
|
||||
Begin
|
||||
ConvertNum(n,ConvNum);
|
||||
result := true;
|
||||
with ConvNum do
|
||||
Begin
|
||||
i := MaxIdx;
|
||||
IF NumRest[i] >= Base then
|
||||
Begin
|
||||
dgt := LowDgt;
|
||||
IF Not(ODD(dgt)) OR (dgt=5) then
|
||||
Begin
|
||||
InsertFound(dgt,n);
|
||||
EXIT;
|
||||
end;
|
||||
end;
|
||||
|
||||
result := false;
|
||||
For i := i downto 1 do
|
||||
Begin
|
||||
dtfac := PotBase[i];
|
||||
val := NumRest[i];
|
||||
For dgt := 0 to Base-1 do
|
||||
Begin
|
||||
IF isPrime(val) then
|
||||
EXIT;
|
||||
inc(val,dtfac);
|
||||
end;
|
||||
end;
|
||||
InsertFound(LowDgt,n);
|
||||
result := true;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
n,i : NativeUint;
|
||||
Begin
|
||||
init;
|
||||
n := Base;
|
||||
repeat
|
||||
If CheckUnprimable(n) then
|
||||
Begin
|
||||
CheckOutPut(n);
|
||||
For i := 1 to Base-1 do
|
||||
Begin
|
||||
IF CheckUnprimableReduced(n+i) then
|
||||
CheckOutPut(n+i);
|
||||
end;
|
||||
end;
|
||||
inc(n,Base);
|
||||
until EndDgtCnt = Base;
|
||||
writeln;
|
||||
For i := 0 to Base-1 do
|
||||
Writeln ('lowest digit ',i:2,' found first ',EndDgtFound[i]:7);
|
||||
writeln;
|
||||
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
|
||||
{$IFNDEF UNIX}readln;{$ENDIF}
|
||||
end.
|
||||
417
Task/Unprimeable-numbers/Pascal/unprimeable-numbers-2.pas
Normal file
417
Task/Unprimeable-numbers/Pascal/unprimeable-numbers-2.pas
Normal file
|
|
@ -0,0 +1,417 @@
|
|||
program unprimable;
|
||||
{$IFDEF FPC}
|
||||
{$Mode Delphi}
|
||||
{$OPTIMIZATION ON,ALL}
|
||||
{$ELSE}
|
||||
//Delphi
|
||||
{$APPTYPE CONSOLE}
|
||||
{$ENDIF}
|
||||
uses
|
||||
sysutils;
|
||||
const
|
||||
Base = 10;
|
||||
dgtcnt = 9;
|
||||
Limit = Base* Base*Base*Base*Base* Base*Base*Base*Base;
|
||||
{
|
||||
Base = 18;
|
||||
dgtcnt = 8;
|
||||
Limit = Base*Base*Base*Base* Base*Base*Base*Base;
|
||||
* }
|
||||
|
||||
PrimeLimit = Limit+Base;
|
||||
{
|
||||
Limit = 1000*1000*1000;
|
||||
dgtcnt = trunc(ln(Limit-1)/ln(Base));
|
||||
PrimeLimit = Trunc(exp(ln(base)*(dgtcnt+1)))+Base;
|
||||
}
|
||||
type
|
||||
TNumVal = array[0..dgtcnt] of NativeUint;
|
||||
TConvNum = record
|
||||
NumRest,
|
||||
Digits : TNumVal;
|
||||
num,
|
||||
MaxIdx : NativeUint;
|
||||
end;
|
||||
|
||||
var //global
|
||||
ConvNum:TConvNum;
|
||||
PotBase: TNumVal;
|
||||
EndDgtFound : array[0..Base-1] of NativeUint;
|
||||
TotalCnt,
|
||||
EndDgtCnt :NativeUint;
|
||||
|
||||
//http://rosettacode.org/wiki/Sieve_of_Eratosthenes#alternative_using_wheel
|
||||
|
||||
var
|
||||
pPrimes : pBoolean;
|
||||
//always initialized with 0 => false at startup
|
||||
primes: array of boolean;
|
||||
|
||||
function BuildWheel: NativeUint;
|
||||
var
|
||||
myPrimes : pBoolean;
|
||||
wheelprimes :array[0..31] of byte;
|
||||
wheelSize,wpno,
|
||||
pr,pw,i, k: NativeUint;
|
||||
begin
|
||||
myPrimes := @primes[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;
|
||||
//turn the wheel (pr-1)-times
|
||||
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);
|
||||
//the new wheelsize
|
||||
WheelSize := k;
|
||||
|
||||
//sieve multiples of the new found prime
|
||||
i:= pr;
|
||||
i := i*i;
|
||||
while i <= k do
|
||||
begin
|
||||
myPrimes[i] := false;
|
||||
inc(i,pr);
|
||||
end;
|
||||
end;
|
||||
until WheelSize >= PrimeLimit;
|
||||
|
||||
//re-insert wheel-primes 1 still stays prime
|
||||
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;
|
||||
var
|
||||
myPrimes : pBoolean;
|
||||
sieveprime,
|
||||
fakt : NativeUint;
|
||||
begin
|
||||
setlength(Primes,PrimeLimit+1);
|
||||
pPrimes := @Primes[0];
|
||||
myPrimes := pPrimes;
|
||||
//pPrimes[1] = true is needed to stop for sieveprime = 2
|
||||
// at //Search next smaller possible prime
|
||||
sieveprime := BuildWheel;
|
||||
//alternative here
|
||||
//fillchar(pPrimes,SizeOf(pPrimes),chr(ord(true)));sieveprime := 2;
|
||||
repeat
|
||||
if myPrimes[sieveprime] then
|
||||
begin
|
||||
//eliminate 'possible prime' multiples of sieveprime
|
||||
//must go downwards
|
||||
//2*2 would unmark 4 -> 4*2 = 8 wouldnt be unmarked
|
||||
fakt := PrimeLimit DIV sieveprime;
|
||||
IF fakt < sieveprime then
|
||||
BREAK;
|
||||
repeat
|
||||
//Unmark
|
||||
myPrimes[sieveprime*fakt] := false;
|
||||
//Search next smaller possible prime
|
||||
repeat
|
||||
dec(fakt);
|
||||
until myPrimes[fakt];
|
||||
until fakt < sieveprime;
|
||||
end;
|
||||
inc(sieveprime);
|
||||
until false;
|
||||
//remove 1
|
||||
myPrimes[1] := false;
|
||||
end;
|
||||
|
||||
procedure Init;
|
||||
var
|
||||
i,val : NativeUint;
|
||||
Begin
|
||||
val := 1;
|
||||
For i := low(TNumVal) to High(TNumVal) do
|
||||
Begin
|
||||
EndDgtFound[i] :=0;
|
||||
PotBase[i] := val;
|
||||
val := val * Base;
|
||||
end;
|
||||
TotalCnt := 0;
|
||||
EndDgtCnt := 0;
|
||||
end;
|
||||
|
||||
procedure OutConvNum(const NConv:TConvNum);
|
||||
var
|
||||
i : NativeInt;
|
||||
Begin
|
||||
with NConv do
|
||||
begin
|
||||
writeln(num,MaxIdx:10);
|
||||
For i := MaxIdx Downto MaxIdx do
|
||||
write(Digits[i]);
|
||||
writeln;
|
||||
For i := MaxIdx Downto MaxIdx do
|
||||
write(NumRest[i]:8);
|
||||
end
|
||||
end;
|
||||
|
||||
procedure IncConvertNum(var NConv:TConvNum);
|
||||
var
|
||||
i,k : NativeInt;
|
||||
Begin
|
||||
with NConv do
|
||||
begin
|
||||
i := 0;
|
||||
repeat
|
||||
k := Digits[i]+1;
|
||||
IF k < Base then
|
||||
Begin
|
||||
Digits[i] := k;
|
||||
BREAK;
|
||||
end
|
||||
else
|
||||
Begin
|
||||
Digits[i] := k-Base;
|
||||
inc(i);
|
||||
end;
|
||||
until i > MaxIdx;
|
||||
IF i > MaxIdx then
|
||||
Begin
|
||||
Digits[i] := 1;
|
||||
MaxIdx := i;
|
||||
end;
|
||||
|
||||
k := num+1;
|
||||
i := MaxIdx;
|
||||
repeat
|
||||
NumRest[i]:= k-Digits[i]*PotBase[i];
|
||||
dec(i);
|
||||
until i < 0;
|
||||
num := k;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure IncConvertNumBase(var NConv:TConvNum);
|
||||
var
|
||||
i,k : NativeInt;
|
||||
Begin
|
||||
with NConv do
|
||||
begin
|
||||
i := 1;
|
||||
Digits[0] := 0;
|
||||
repeat
|
||||
k := Digits[i]+1;
|
||||
IF k < Base then
|
||||
Begin
|
||||
Digits[i] := k;
|
||||
BREAK;
|
||||
end
|
||||
else
|
||||
Begin
|
||||
Digits[i] := k-Base;
|
||||
inc(i);
|
||||
end;
|
||||
until i > MaxIdx;
|
||||
IF i > MaxIdx then
|
||||
Begin
|
||||
Digits[i] := 1;
|
||||
MaxIdx := i;
|
||||
end;
|
||||
k := num+Base;
|
||||
i := MaxIdx;
|
||||
repeat
|
||||
NumRest[i]:= k-Digits[i]*PotBase[i];
|
||||
dec(i);
|
||||
until i < 0;
|
||||
num := k;
|
||||
end;
|
||||
end;
|
||||
|
||||
Procedure ConvertNum(n: NativeUint;var NConv:TConvNum);
|
||||
//extract digit position replace by "0" to get NumRest
|
||||
// 173 -> 170 -> 103 -> 073
|
||||
var
|
||||
i, dgt,n_red,n_div: NativeUint;
|
||||
begin
|
||||
i := 0;
|
||||
with NConv do
|
||||
Begin
|
||||
num := n;
|
||||
n_red := n;
|
||||
repeat
|
||||
n_div := n_red DIV Base;
|
||||
dgt := n_red-Base*n_div;
|
||||
n_red := n_div;
|
||||
Digits[i] := dgt;
|
||||
NumRest[i]:= n-dgt*PotBase[i];
|
||||
inc(i);
|
||||
until (n_red= 0)OR (i > High(TNumVal));
|
||||
MaxIdx := i-1;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure InsertFound(dgt,n:NativeUInt);
|
||||
Begin
|
||||
IF EndDgtFound[dgt] = 0 then
|
||||
Begin
|
||||
EndDgtFound[dgt] := n;
|
||||
inc(EndDgtCnt);
|
||||
end;
|
||||
end;
|
||||
|
||||
function CheckUnprimable(const ConvNum:TConvNum):boolean;
|
||||
var
|
||||
myPrimes : pBoolean;
|
||||
val,dgt,i,dtfac: NativeUint;
|
||||
Begin
|
||||
myPrimes := pPrimes;
|
||||
result := false;
|
||||
with ConvNum do
|
||||
Begin
|
||||
//lowest digit. Check only resulting odd numbers num > base
|
||||
val := NumRest[0];
|
||||
dgt := 1- (val AND 1);
|
||||
repeat
|
||||
IF myPrimes[val+dgt] then
|
||||
EXIT;
|
||||
inc(dgt,2);
|
||||
until dgt >= Base;
|
||||
|
||||
For i := 1 to MaxIdx do
|
||||
Begin
|
||||
val := NumRest[i];
|
||||
dtfac := PotBase[i];
|
||||
IF (val >= BASE) then
|
||||
Begin
|
||||
IF NOt(Odd(val)) AND NOT(ODD(dtfac)) then
|
||||
continue;
|
||||
For dgt := 0 to Base-1 do
|
||||
Begin
|
||||
IF myPrimes[val] then
|
||||
EXIT;
|
||||
inc(val,dtfac);
|
||||
end;
|
||||
end
|
||||
else
|
||||
Begin
|
||||
For dgt := 0 to Base-1 do
|
||||
Begin
|
||||
IF myPrimes[val] then
|
||||
EXIT;
|
||||
inc(val,dtfac);
|
||||
end;
|
||||
end
|
||||
end;
|
||||
inc(TotalCnt);
|
||||
result := true;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
n,i,Lmt,Lmt10 : NativeUint;
|
||||
Begin
|
||||
init;
|
||||
Sieve;
|
||||
n := Base;
|
||||
Lmt10 := 10;
|
||||
Lmt := Base;
|
||||
ConvertNum(n,ConvNum);
|
||||
writeln('Base ',ConvNum.num);
|
||||
//InsertFound takes a lot of time.So check it as long as neccessary
|
||||
while EndDgtCnt <Base do
|
||||
Begin
|
||||
If CheckUnprimable(ConvNum) then
|
||||
Begin
|
||||
InsertFound(ConvNum.Digits[0],n);
|
||||
For i := 1 to Base-1 do
|
||||
Begin
|
||||
inc(n);
|
||||
IncConvertNum(ConvNum);
|
||||
IF CheckUnprimable(ConvNum) then
|
||||
InsertFound(ConvNum.Digits[0],n);
|
||||
end;
|
||||
inc(n);
|
||||
IncConvertNum(ConvNum);
|
||||
end
|
||||
else
|
||||
Begin
|
||||
inc(n,Base);
|
||||
IncConvertNumBase(ConvNum);
|
||||
end;
|
||||
if n >= Lmt10 then
|
||||
Begin
|
||||
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
|
||||
Lmt10 := Lmt10*10;
|
||||
end;
|
||||
if (Base <> 10) AND (n >= Lmt) then
|
||||
Begin
|
||||
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
|
||||
Lmt := Lmt*Base;
|
||||
end;
|
||||
end;
|
||||
//All found
|
||||
repeat
|
||||
If CheckUnprimable(ConvNum) then
|
||||
Begin
|
||||
For i := 1 to Base-1 do
|
||||
Begin
|
||||
inc(n);
|
||||
IncConvertNum(ConvNum);
|
||||
CheckUnprimable(ConvNum)
|
||||
end;
|
||||
inc(n);
|
||||
IncConvertNum(ConvNum);
|
||||
end
|
||||
else
|
||||
Begin
|
||||
inc(n,Base);
|
||||
IncConvertNumBase(ConvNum);
|
||||
end;
|
||||
|
||||
if n >= Lmt10 then
|
||||
Begin
|
||||
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
|
||||
Lmt10 := Lmt10*10;
|
||||
end;
|
||||
|
||||
if (Base <> 10) AND (n >= Lmt) then
|
||||
Begin
|
||||
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
|
||||
Lmt := Lmt*Base;
|
||||
end;
|
||||
until n >= Limit;
|
||||
writeln;
|
||||
For i := 0 to Base-1 do
|
||||
Writeln ('lowest digit ',i:2,' found first ',EndDgtFound[i]:7);
|
||||
writeln;
|
||||
writeln('There are ',TotalCnt,' unprimable numbers upto ',n);
|
||||
setlength(Primes,0);
|
||||
end.
|
||||
Loading…
Add table
Add a link
Reference in a new issue