Own digits power sum: Difference between revisions
Content added Content deleted
(→Combinations with repetitions: Separated Ruby and Raku examples.) |
m (→{{header|Pascal}}: extend to 19 digits one more than ruby,hoping overflow will not generate the needed digits.) |
||
Line 682: | Line 682: | ||
uses |
uses |
||
SysUtils; |
SysUtils; |
||
const |
const |
||
MAXBASE = 10 |
MAXBASE = 10; |
||
MaxDgtVal = MAXBASE - 1; |
MaxDgtVal = MAXBASE - 1; |
||
MaxDgtCount = 19; |
|||
type |
type |
||
tDgtCnt = 0..MaxDgtCount; |
|||
tValues = 0..MaxDgtVal; |
|||
tUsedDigits = array[0..31] of Int8; |
|||
tPower = array[tValues] of Uint64; |
|||
var |
var |
||
PowerDgt: array[ |
PowerDgt: array[tDgtCnt] of tPower; |
||
UD :tUsedDigits; |
|||
CombIdx: array of Int8; |
CombIdx: array of Int8; |
||
Numbers : array of |
Numbers : array of Uint64; |
||
rec_cnt : NativeInt; |
rec_cnt : NativeInt; |
||
function InitCombIdx(ElemCount: Byte): pbyte; |
function InitCombIdx(ElemCount: Byte): pbyte; |
||
begin |
begin |
||
Line 703: | Line 705: | ||
Result := @CombIdx[0]; |
Result := @CombIdx[0]; |
||
end; |
end; |
||
function Init(ElemCount:byte):pByte; |
|||
var |
|||
pP1,Pp2 : pUint64; |
|||
i, j: Int32; |
|||
begin |
|||
pP1 := @PowerDgt[low(tDgtCnt)]; |
|||
for i in tValues do |
|||
pP1[i] := 1; |
|||
pP1[0] := 0; |
|||
for j := low(tDgtCnt) + 1 to High(tDgtCnt) do |
|||
Begin |
|||
pP2 := @PowerDgt[j]; |
|||
for i in tValues do |
|||
pP2[i] := pP1[i]*i; |
|||
pP1 := pP2; |
|||
end; |
|||
result := InitCombIdx(ElemCount); |
|||
end; |
|||
function NextCombWithRep(pComb: pByte; MaxVal, ElemCount: UInt32): boolean; |
function NextCombWithRep(pComb: pByte; MaxVal, ElemCount: UInt32): boolean; |
||
var |
var |
||
i, |
i,dgt: NativeInt; |
||
begin |
begin |
||
i := -1; |
i := -1; |
||
Line 715: | Line 736: | ||
break; |
break; |
||
until i > ElemCount; |
until i > ElemCount; |
||
Result := i >= ElemCount; |
Result := i >= ElemCount; |
||
dgt +=1; |
dgt +=1; |
||
Line 721: | Line 743: | ||
i -= 1; |
i -= 1; |
||
until i < 0; |
until i < 0; |
||
end; |
|||
function Init(ElemCount:byte):pByte; |
|||
var |
|||
i, j: tDgtVal; |
|||
begin |
|||
for i in tDgtVal do |
|||
PowerDgt[low(tDgtVal), i] := 1; |
|||
for j := low(tDgtVal) + 1 to High(tDgtVal) do |
|||
for i in tDgtVal do |
|||
PowerDgt[j, i] := PowerDgt[j - 1, i] * i; |
|||
result := InitCombIdx(ElemCount); |
|||
end; |
end; |
||
function GetPowerSum(minpot:nativeInt;digits:pbyte;var UD_tmp :tUsedDigits):NativeInt; |
function GetPowerSum(minpot:nativeInt;digits:pbyte;var UD_tmp :tUsedDigits):NativeInt; |
||
var |
var |
||
pPower : pUint64; |
pPower : pUint64; |
||
res,r |
res,r : Uint64; |
||
dgt :Int32; |
|||
begin |
begin |
||
pPower := @PowerDgt[minpot,0]; |
|||
dgt := minpot-1; |
|||
res := 0; |
res := 0; |
||
pPower := @PowerDgt[dgt,0]; |
|||
repeat |
repeat |
||
r := res; |
|||
res += pPower[digits[dgt]]; |
res += pPower[digits[dgt]]; |
||
dgt -=1; |
|||
until dgt<0; |
|||
//convert res into digits |
|||
result := minPot; |
result := minPot; |
||
repeat |
repeat |
||
dec(result); |
|||
r := res DIV MAXBASE; |
r := res DIV MAXBASE; |
||
UD_tmp[res-r*MAXBASE]-= 1; |
UD_tmp[res-r*MAXBASE]-= 1; |
||
res := r; |
res := r; |
||
dec(result); |
|||
until r = 0; |
until r = 0; |
||
end; |
end; |
||
procedure calcNum(digits:pbyte); |
procedure calcNum(minPot:Int32;digits:pbyte); |
||
var |
var |
||
UD :tUsedDigits; |
|||
res: Uint64; |
|||
i: nativeInt; |
|||
begin |
begin |
||
fillchar(UD,SizeOf(UD),#0); |
fillchar(UD,SizeOf(UD),#0); |
||
For i := minpot-1 downto 0 do |
|||
UD[digits[i]]+=1; |
|||
i := GetPowerSum(minpot,digits,UD); |
|||
repeat |
|||
dgt := digits[minPot]; |
|||
if dgt = 0 then |
|||
break; |
|||
UD[dgt]+=1; |
|||
inc(minPot); |
|||
until minPot > MaxDgtVal; |
|||
If (minPot<2) or (digits[0] = 1) then |
|||
EXIT; |
|||
//powersum to small |
|||
repeat |
|||
if i > 0 then |
|||
EXIT; |
|||
dgt := GetPowerSum(minpot,digits,UD_tmp); |
|||
if i = 0 then |
|||
begin |
|||
if dgt > 0 then |
|||
while (i <= minPot) and (UD[digits[i]] = 0) do |
|||
break; |
|||
i +=1; |
|||
// all digits are in sum then solution found. |
|||
if i > minPot then |
|||
begin |
begin |
||
res := 0; |
|||
for i := minpot-1 downto 0 do |
|||
res += PowerDgt[minpot,digits[i]]; |
|||
setlength(Numbers, Length(Numbers) + 1); |
|||
if dgt > MaxDgtVal then |
|||
Numbers[high(Numbers)] := res; |
|||
res := 0; |
|||
for dgt := minpot-1 downto 0 do |
|||
res += PowerDgt[minpot,digits[dgt]]; |
|||
setlength(Numbers, Length(Numbers) + 1); |
|||
Numbers[high(Numbers)] := res; |
|||
BREAK; |
|||
end; |
|||
end; |
end; |
||
end; |
|||
//try one more 0 |
|||
minPot +=1; |
|||
until minPot > MaxDgtVal; |
|||
end; |
end; |
||
const |
|||
rounds = 128; |
|||
var |
var |
||
digits : pByte; |
digits : pByte; |
||
Line 810: | Line 804: | ||
tmp: Uint64; |
tmp: Uint64; |
||
i, j : Int32; |
i, j : Int32; |
||
begin |
begin |
||
digits := Init( |
digits := Init(MaxDgtCount); |
||
//warm up |
|||
For i := 1 to 50 do |
|||
Begin |
|||
setlength(numbers,0); |
|||
digits := InitCombIdx(MaxDgtVal); |
|||
repeat |
|||
calcnum(digits); |
|||
until NextCombWithRep(digits,MaxDgtVal,MaxDgtVal); |
|||
end; |
|||
//warm up |
|||
T0 := GetTickCount64; |
T0 := GetTickCount64; |
||
rec_cnt := 0; |
rec_cnt := 0; |
||
For i := |
For i := 3 to MaxDgtCount do |
||
Begin |
Begin |
||
digits := InitCombIdx(MaxDgtCount); |
|||
setlength(numbers,0); |
|||
digits := InitCombIdx(MaxDgtVal); |
|||
repeat |
repeat |
||
calcnum(digits); |
calcnum(i,digits); |
||
inc(rec_cnt); |
inc(rec_cnt); |
||
until NextCombWithRep(digits,MaxDgtVal, |
until NextCombWithRep(digits,MaxDgtVal,i); |
||
end; |
end; |
||
T0 := GetTickCount64-T0; |
T0 := GetTickCount64-T0; |
||
writeln(rec_cnt DIV rounds,' recursions in runtime ',T0/rounds:5:2,' ms'); |
writeln(rec_cnt DIV rounds,' recursions in runtime ',T0/rounds:5:2,' ms'); |
||
Line 847: | Line 830: | ||
Numbers[j] := tmp; |
Numbers[j] := tmp; |
||
end; |
end; |
||
setlength(Numbers, j + 1); |
setlength(Numbers, j + 1); |
||
for i := 0 to High(Numbers) do |
for i := 0 to High(Numbers) do |
||
writeln(i+1:3,Numbers[i]: |
writeln(i+1:3,Numbers[i]:20); |
||
{$IFDEF WINDOWS} |
{$IFDEF WINDOWS} |
||
readln; |
readln; |
||
{$ENDIF} |
{$ENDIF} |
||
end. |
end. |
||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre style="height:180px"> |
<pre style="height:180px"> |
||
TIO.RUN CPU share: 99.49 % |
|||
//doing rounds = 1024 NextCombWithRep without calcnum(digits); takes: 48620 recursions in runtime 0.23 ms |
|||
20029944 recursions in runtime 1755.00 ms |
|||
TIO.RUN CPU share: 99.04 % |
|||
found 41 |
|||
48620 recursions in runtime 3.63 ms //best on TIO.RUN ..5.11 ms |
|||
1 153 |
|||
found 22 |
|||
2 370 |
|||
3 371 |
|||
4 407 |
|||
5 1634 |
|||
6 8208 |
|||
7 9474 |
|||
8 54748 |
|||
9 92727 |
|||
10 93084 |
|||
11 548834 |
|||
12 1741725 |
|||
13 4210818 |
|||
14 9800817 |
|||
15 9926315 |
|||
16 24678050 |
|||
17 24678051 |
|||
16 24678050 |
|||
18 88593477 |
|||
17 24678051 |
|||
19 146511208 |
|||
18 88593477 |
|||
20 472335975 |
|||
19 146511208 |
|||
21 534494836 |
|||
20 472335975 |
|||
22 912985153 |
|||
21 534494836 |
|||
23 4679307774 |
|||
22 912985153</pre> |
|||
24 32164049650 |
|||
25 32164049651 |
|||
26 40028394225 |
|||
27 42678290603 |
|||
28 44708635679 |
|||
29 49388550606 |
|||
30 82693916578 |
|||
31 94204591914 |
|||
32 28116440335967 |
|||
33 4338281769391370 |
|||
34 4338281769391371 |
|||
35 21897142587612075 |
|||
36 35641594208964132 |
|||
37 35875699062250035 |
|||
38 1517841543307505039 |
|||
39 3289582984443187032 |
|||
40 4498128791164624869 |
|||
41 4929273885928088826</pre> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |