Untouchable numbers: Difference between revisions
Content added Content deleted
m (→{{header|Pascal}}: corrected SieveOneSieve Uint64(1) shl.. not 1 shl.., the 1 is Uint32 ...#@!... Now only use TIO.RUN) |
m (→{{header|Pascal}}: reduced to only calc sum of divisors nearly halves time on TIO.RUN.Longer list of count of untouchable numbers) |
||
Line 889: | Line 889: | ||
There are 13863 untouchable numbers ≤ 100000.</pre> |
There are 13863 untouchable numbers ≤ 100000.</pre> |
||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
modified [[Factors_of_an_integer#using_Prime_decomposition]]<BR> |
modified [[Factors_of_an_integer#using_Prime_decomposition]] to calculate only sum of divisors<BR> |
||
Appended a list of count of untouchable numbers out of math.dartmouth.edu/~carlp/uupaper3.pdf<BR> |
|||
Nigel is still right, that this procedure is not the way to get proven results. |
|||
<lang pascal>program UntouchableNumbers; |
<lang pascal>program UntouchableNumbers; |
||
// gets factors of consecutive integers fast |
|||
// limited to 1.2e11 ( = sqr(821641)) aka max(smallprimes) |
|||
{$IFDEF FPC} |
{$IFDEF FPC} |
||
{$MODE DELPHI} {$OPTIMIZATION ON,ALL} {$COPERATORS ON} |
{$MODE DELPHI} {$OPTIMIZATION ON,ALL} {$COPERATORS ON} |
||
Line 900: | Line 899: | ||
{$ENDIF} |
{$ENDIF} |
||
uses |
uses |
||
sysutils,strutils |
sysutils,strutils |
||
{$IFDEF WINDOWS},Windows{$ENDIF} |
{$IFDEF WINDOWS},Windows{$ENDIF} |
||
; |
; |
||
const |
const |
||
//100*1000*1000;//10*1000*1000;//5*1000*1000;//1000*1000; |
//100*1000*1000;//10*1000*1000;//5*1000*1000;//1000*1000; |
||
LIMIT = 1000*1000; |
LIMIT = 5*1000*1000; |
||
//384;// |
//384;//152;//104;//64; |
||
LIMIT_mul = |
LIMIT_mul = 104; |
||
//###################################################################### |
//###################################################################### |
||
//gets sum of divisors of consecutive integers fast |
|||
//prime decomposition |
|||
const |
const |
||
SizePrDeFe = |
SizePrDeFe = 16*8192;//*size of(tprimeFac) =16 byte 2 Mb ~ level 3 cache |
||
type |
type |
||
tdigits = array [0..31] of Uint32; |
tdigits = array [0..31] of Uint32; |
||
//the first number with 12 different prime factors = |
|||
//2*3*5*7*11*13*17*19*23*29*31*37 = 7,42e12 |
|||
//56 byte |
|||
tprimeFac = packed record |
tprimeFac = packed record |
||
pfSumOfDivs, |
pfSumOfDivs, |
||
pfRemain |
pfRemain : Uint64; |
||
pfpotPrimIdx : array[0..11] of word; |
|||
pfDivCnt : Uint16; |
|||
pfpotMax : array[0..12] of byte; |
|||
pfMaxIdx : byte; |
|||
end; |
end; |
||
tpPrimeFac = ^tprimeFac; |
tpPrimeFac = ^tprimeFac; |
||
Line 932: | Line 924: | ||
var |
var |
||
{$ALIGN |
{$ALIGN 16} |
||
SmallPrimes: tPrimes; |
|||
{$ALIGN 32} |
|||
PrimeDecompField :tPrimeDecompField; |
PrimeDecompField :tPrimeDecompField; |
||
{$ALIGN 16} |
|||
SmallPrimes: tPrimes; |
|||
pdfIDX,pdfOfs: NativeInt; |
pdfIDX,pdfOfs: NativeInt; |
||
Line 979: | Line 971: | ||
flipflop := 3-flipflop; |
flipflop := 3-flipflop; |
||
until (p > MAXLIMIT) OR (j>High(SmallPrimes)); |
until (p > MAXLIMIT) OR (j>High(SmallPrimes)); |
||
end; |
|||
function smplPrimeDecomp(n:Uint64):tprimeFac; |
|||
var |
|||
pr,i,pot,fac,q :NativeUInt; |
|||
Begin |
|||
with result do |
|||
Begin |
|||
pfDivCnt := 1; |
|||
pfSumOfDivs := 1; |
|||
pfRemain := n; |
|||
pfMaxIdx := 0; |
|||
pfpotPrimIdx[0] := 1; |
|||
pfpotMax[0] := 0; |
|||
i := 0; |
|||
while i < High(SmallPrimes) do |
|||
begin |
|||
pr := SmallPrimes[i]; |
|||
q := n DIV pr; |
|||
//if n < pr*pr |
|||
if pr > q then |
|||
BREAK; |
|||
if n = pr*q then |
|||
Begin |
|||
pfpotPrimIdx[pfMaxIdx] := i; |
|||
pot := 0; |
|||
fac := pr; |
|||
repeat |
|||
n := q; |
|||
q := n div pr; |
|||
pot+=1; |
|||
fac *= pr; |
|||
until n <> pr*q; |
|||
pfpotMax[pfMaxIdx] := pot; |
|||
pfDivCnt *= pot+1; |
|||
pfSumOfDivs *= (fac-1)DIV(pr-1); |
|||
inc(pfMaxIdx); |
|||
end; |
|||
inc(i); |
|||
end; |
|||
pfRemain := n; |
|||
if n > 1 then |
|||
Begin |
|||
pfDivCnt *= 2; |
|||
pfSumOfDivs *= n+1 |
|||
end; |
|||
end; |
|||
end; |
end; |
||
Line 1,054: | Line 998: | ||
end; |
end; |
||
function |
function IncByOneInBase(var dgt:tDigits;base:NativeInt):NativeInt; |
||
var |
var |
||
q :NativeInt; |
q :NativeInt; |
||
Line 1,068: | Line 1,012: | ||
dgt[result] := q; |
dgt[result] := q; |
||
result +=1; |
result +=1; |
||
end; |
|||
procedure CalcSumOfDivs(var pdf:tPrimeDecompField;var dgt:tDigits;n,k,pr:Uint64); |
|||
var |
|||
fac,s :Uint64; |
|||
j : Int32; |
|||
Begin |
|||
//j is power of prime |
|||
j := CnvtoBASE(dgt,n+k,pr); |
|||
repeat |
|||
fac := 1; |
|||
s := 1; |
|||
repeat |
|||
fac *= pr; |
|||
dec(j); |
|||
s += fac; |
|||
until j<= 0; |
|||
with pdf[k] do |
|||
Begin |
|||
pfSumOfDivs *= s; |
|||
pfRemain := pfRemain DIV fac; |
|||
end; |
|||
j := IncByOneInBase(dgt,pr); |
|||
k += pr; |
|||
until k >= SizePrDeFe; |
|||
end; |
end; |
||
Line 1,073: | Line 1,042: | ||
var |
var |
||
dgt:tDigits; |
dgt:tDigits; |
||
i,j,k,pr |
i,j,k,pr,n,MaxP : Uint64; |
||
begin |
begin |
||
n := pdfOfs; |
n := pdfOfs; |
||
Line 1,083: | Line 1,052: | ||
with pdf[i] do |
with pdf[i] do |
||
Begin |
Begin |
||
pfDivCnt := 1; |
|||
pfSumOfDivs := 1; |
pfSumOfDivs := 1; |
||
pfRemain := n+i; |
pfRemain := n+i; |
||
pfMaxIdx := 0; |
|||
pfpotPrimIdx[0] := 0; |
|||
pfpotMax[0] := 0; |
|||
end; |
end; |
||
end; |
end; |
||
Line 1,100: | Line 1,065: | ||
begin |
begin |
||
j := BsfQWord(n+i); |
j := BsfQWord(n+i); |
||
pfMaxIdx := 1; |
|||
pfpotPrimIdx[0] := 0; |
|||
pfpotMax[0] := j; |
|||
pfRemain := (n+i) shr j; |
pfRemain := (n+i) shr j; |
||
pfSumOfDivs := (Uint64(1) shl (j+1))-1; |
pfSumOfDivs := (Uint64(1) shl (j+1))-1; |
||
// writeln(n+i,' # ',j,' ## ',pfRemain,' ### ',pfSumOfDivs); |
|||
pfDivCnt := j+1; |
|||
end; |
end; |
||
i += 2; |
i += 2; |
||
Line 1,139: | Line 1,099: | ||
//no need to use higher primes |
//no need to use higher primes |
||
if |
if pr > maxP then |
||
BREAK; |
BREAK; |
||
CalcSumOfDivs(pdf,dgt,n,k,pr); |
|||
//j is power of prime |
|||
j := CnvtoBASE(dgt,n+k,pr); |
|||
repeat |
|||
with pdf[k] do |
|||
Begin |
|||
pfpotPrimIdx[pfMaxIdx] := i; |
|||
pfpotMax[pfMaxIdx] := j; |
|||
pfDivCnt *= j+1; |
|||
fac := pr; |
|||
repeat |
|||
pfRemain := pfRemain DIV pr; |
|||
dec(j); |
|||
fac *= pr; |
|||
until j<= 0; |
|||
pfSumOfDivs *= (fac-1)DIV(pr-1); |
|||
inc(pfMaxIdx); |
|||
k += pr; |
|||
j := IncByBaseInBase(dgt,pr); |
|||
end; |
|||
until k >= SizePrDeFe; |
|||
until false; |
until false; |
||
Line 1,171: | Line 1,112: | ||
j := pfRemain; |
j := pfRemain; |
||
if j <> 1 then |
if j <> 1 then |
||
begin |
|||
pfSumOFDivs *= (j+1); |
pfSumOFDivs *= (j+1); |
||
pfDivCnt *=2; |
|||
end; |
|||
end; |
end; |
||
end; |
end; |
||
Line 1,251: | Line 1,189: | ||
repeat |
repeat |
||
inc(prmEndIdx); |
inc(prmEndIdx); |
||
until smallprimes[prmEndIdx] > trunc( |
until smallprimes[prmEndIdx] > trunc(sqrt(Limit)); |
||
writeln('LIMIT = ',Numb2USA(IntToStr(LIMIT))); |
|||
writeln(prmEndIdx:10,smallprimes[prmEndIdx]:10); |
writeln(prmEndIdx:10,smallprimes[prmEndIdx]:10); |
||
writeln(LIMIT_mul); |
writeln('factor beyond LIMIT ',LIMIT_mul); |
||
n := 0; |
n := 0; |
||
Line 1,271: | Line 1,210: | ||
end; |
end; |
||
until n >LIMIT; |
until n >LIMIT; |
||
writeln('runtime for n<= LIMIT ',(GetTickCount64-T0)/1000:0:3,' s'); |
writeln('runtime for n<= LIMIT ',(GetTickCount64-T0)/1000:0:3,' s'); |
||
writeln('Check the rest ',Numb2USA(IntToStr((LIMIT_mul-1)*Limit))); |
writeln('Check the rest ',Numb2USA(IntToStr((LIMIT_mul-1)*Limit))); |
||
Line 1,283: | Line 1,223: | ||
if n = lim then |
if n = lim then |
||
Begin |
Begin |
||
writeln |
writeln(lim:10,k:10); |
||
lim *= 10; |
lim *= 10; |
||
end; |
end; |
||
Line 1,293: | Line 1,233: | ||
if n = lim then |
if n = lim then |
||
Begin |
Begin |
||
writeln |
writeln(lim:10,k:10); |
||
lim += LIMIT DIV 10; |
lim += LIMIT DIV 10; |
||
end; |
end; |
||
k += 1-pUntouch[n]; |
k += 1-pUntouch[n]; |
||
end; |
end; |
||
end. |
end.</lang> |
||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
TIO.RUN |
TIO.RUN |
||
LIMIT = 5,000,000 |
|||
runtime for n<= LIMIT 0.070 s |
|||
331 2237 |
|||
Check the rest 63,000,000 |
|||
factor beyond LIMIT 104 |
|||
runtime 4.214 s |
|||
runtime for n<= LIMIT 0.272 s |
|||
Check the rest 515,000,000 |
|||
runtime 19.052 s |
|||
10 2 |
10 2 |
||
100 5 |
100 5 |
||
1000 89 |
|||
10000 1212 |
|||
100000 13863 |
|||
1000000 150232 |
|||
1500000 227297 |
|||
2000000 305290 |
|||
2500000 383422 |
|||
3000000 462110 |
|||
3500000 540769 |
|||
4000000 619638 |
|||
4500000 698504 |
|||
5000000 777672 |
|||
1,000,000 150,232 |
|||
//url=https://math.dartmouth.edu/~carlp/uupaper3.pdf |
//url=https://math.dartmouth.edu/~carlp/uupaper3.pdf |
||
100000 13863 |
|||
200000 28572 |
|||
300000 43515 |
|||
400000 58459 |
|||
500000 73565 |
|||
600000 88828 |
|||
700000 104062 |
|||
800000 119302 |
|||
900000 134758 |
|||
1000000 150232 |
|||
2000000 305290 |
|||
3000000 462110 |
|||
4000000 619638 |
|||
5000000 777672 |
|||
6000000 936244 |
6000000 936244 |
||
7000000 1095710 |
7000000 1095710 |