Smallest power of 6 whose decimal expansion contains n: Difference between revisions
Content added Content deleted
Drkameleon (talk | contribs) (added Arturo) |
m (→{{header|Pascal}}: corrected wrong copy (missing letter) . Minimal improvement) |
||
Line 917: | Line 917: | ||
=={{header|Pascal}}== |
=={{header|Pascal}}== |
||
{{ |
==={{header|Free Pascal}}=== |
||
Doing long multiplikation like in primorial task.<BR>I used to check every numberstring one after the other on one 6^ n string.Gets really slow on high n<BR>After a closer look into [[Phix|Smallest_power_of_6_whose_decimal_expansion_contains_n#Phix]] I applied a slghtly modified version of Pete, to get down < 10 secs on my 2200G for DIGITS = 7.TIO.RUN is slower. |
Doing long multiplikation like in primorial task.<BR>I used to check every numberstring one after the other on one 6^ n string.Gets really slow on high n<BR>After a closer look into [[Phix|Smallest_power_of_6_whose_decimal_expansion_contains_n#Phix]] I applied a slghtly modified version of Pete, to get down < 10 secs on my 2200G for DIGITS = 7.TIO.RUN is slower. |
||
<syntaxhighlight lang="pascal">program PotOf6; |
<syntaxhighlight lang="pascal">program PotOf6; |
||
//First occurence of a numberstring with max DIGTIS digits in 6^n |
//First occurence of a numberstring with max DIGTIS digits in 6^n |
||
{$IFDEF FPC} |
{$IFDEF FPC} |
||
{$MODE DELPHI} |
{$MODE DELPHI} {$Optimization ON,ALL} {$COPERATORS ON} |
||
{$ENDIF} |
|||
{$Optimization ON,ALL} |
|||
{$IFDEF WINDOWS} |
|||
{$ELSE} |
|||
{$APPTYPE CONSOLE} |
{$APPTYPE CONSOLE} |
||
{$ENDIF} |
{$ENDIF} |
||
Line 931: | Line 931: | ||
sysutils; |
sysutils; |
||
const |
const |
||
//decimal places used by multiplication and for string conversion |
|||
POT_LIMIT = 70000; |
|||
calcDigits = 8; |
|||
67584 99999998 46238296 |
|||
// DIGITS = 8;POT_LIMIT = 68479; |
|||
DIGITS = 7;POT_LIMIT = 21798; |
|||
Found: 100000000 Time used 148.584 secs} |
|||
// DIGITS = 6;POT_LIMIT = 6120; |
|||
// DIGITS = 5;POT_LIMIT = 1736; |
|||
// DIGITS = 4;POT_LIMIT = 444; |
|||
// DIGITS = 3;POT_LIMIT = 147; |
|||
// DIGITS = 2;POT_LIMIT = 46; |
|||
type |
type |
||
tMulElem = Uint32; |
tMulElem = Uint32; |
||
Line 947: | Line 951: | ||
foundStr :Ansistring; |
foundStr :Ansistring; |
||
end; |
end; |
||
var |
var |
||
{$ALIGN 32} |
|||
PotArrN : tPotArrN; |
PotArrN : tPotArrN; |
||
{$ALIGN 32} |
|||
StrDec4Dgts : array[0..9999] of String[4]; |
|||
{$ALIGN 32} |
|||
Str_Found : array of tFound; |
|||
Pot_N_str : AnsiString; |
Pot_N_str : AnsiString; |
||
Str_Found : array of tFound; |
|||
FirstMissing :NativeInt; |
FirstMissing :NativeInt; |
||
T0 : INt64; |
T0 : INt64; |
||
procedure |
procedure Init_StrDec4Dgts; |
||
var |
|||
MaxMulIdx : NativeInt; |
|||
Begin |
|||
MaxMulIdx := trunc(POT_LIMIT*ln(number)/ln(10)/9+2); |
|||
setlength(PotArrN[0],MaxMulIdx); |
|||
setlength(PotArrN[1],MaxMulIdx); |
|||
PotArrN[0,0] := 1; |
|||
end; |
|||
function Mul_N(var Mul1,Mul2:tMul;limit,n:Uint32):NativeInt; |
|||
//Mul2 = n*Mul1. n must be < LongWordDec ! |
|||
const |
|||
LongWordDec = 1000*1000*1000; |
|||
var |
var |
||
s : string[4]; |
|||
i : integer; |
|||
a,b,c,d : char; |
|||
begin |
begin |
||
i := 0; |
|||
s := '0000'; |
|||
For a := '0' to '9' do |
|||
Begin |
|||
result :=0; |
|||
s[1] := a; |
|||
repeat |
|||
For b := '0' to '9' do |
|||
begin |
|||
Carry := prod Div LongWordDec; |
|||
s[2]:=b; |
|||
For c := '0' to '9' do |
|||
inc(result); |
|||
begin |
|||
s[3] := c; |
|||
For d := '0' to '9' do |
|||
begin |
|||
else |
|||
s[4] := d; |
|||
StrDec4Dgts[i]:= s; |
|||
inc(i); |
|||
end; |
|||
end; |
|||
end; |
|||
end; |
|||
end; |
end; |
||
Line 1,001: | Line 1,002: | ||
exit; |
exit; |
||
end; |
end; |
||
toIdx := 4*(toIdx DIV 3)+toIdx MOD 3; |
toIdx := 4*(toIdx DIV 3)+toIdx MOD 3 +1 ; |
||
inc(toIdx); |
|||
setlength(result,toIdx); |
setlength(result,toIdx); |
||
repeat |
repeat |
||
result[toIdx] := s[FromIdx]; |
result[toIdx] := s[FromIdx]; |
||
result[toIdx-1] := s[FromIdx-1]; |
result[toIdx-1] := s[FromIdx-1]; |
||
result[toIdx-2] := s[FromIdx-2]; |
result[toIdx-2] := s[FromIdx-2]; |
||
Line 1,018: | Line 1,018: | ||
dec(fromIdx); |
dec(fromIdx); |
||
end; |
end; |
||
end; |
|||
procedure Init_Mul(number:NativeInt); |
|||
var |
|||
MaxMulIdx : NativeInt; |
|||
Begin |
|||
MaxMulIdx := trunc(POT_LIMIT*ln(number)/ln(10)/calcDigits+2); |
|||
setlength(PotArrN[0],MaxMulIdx); |
|||
setlength(PotArrN[1],MaxMulIdx); |
|||
PotArrN[0,0] := 1; |
|||
end; |
|||
function Mul_6(var Mul1,Mul2:tMul;limit:Uint32):NativeInt; |
|||
//Mul2 = n*Mul1. n must be < LongWordDec ! |
|||
const |
|||
LongWordDec = 100*1000*1000; |
|||
var |
|||
pM1,pM2 : tpMul; |
|||
carry,prod : Uint64; |
|||
begin |
|||
pM1 := @Mul1[0]; |
|||
pM2 := @Mul2[0]; |
|||
carry := 0; |
|||
result :=0; |
|||
repeat |
|||
prod := 6*pM1[result]+Carry; |
|||
Carry := prod Div LongWordDec; |
|||
pM2[result] := Prod - Carry*LongWordDec; |
|||
inc(result); |
|||
until result > limit; |
|||
IF Carry <> 0 then |
|||
pM2[result] := Carry |
|||
else |
|||
dec(result); |
|||
end; |
end; |
||
procedure ConvToStr(var s:Ansistring;const Mul:tMul;i:NativeInt); |
procedure ConvToStr(var s:Ansistring;const Mul:tMul;i:NativeInt); |
||
var |
var |
||
s8: string[8]; |
|||
pS : pChar; |
pS : pChar; |
||
j,k : NativeInt; |
j,k,d,m : NativeInt; |
||
begin |
begin |
||
j := (i+1)*calcDigits; |
|||
j := (i+1)*9; |
|||
setlength(s,j+1); |
setlength(s,j+1); |
||
pS := |
pS := @s[1]; |
||
m := Mul[i]; |
|||
// fill complete with '0' |
|||
str(Mul[i],s8); |
|||
j := length(s8); |
|||
str(Mul[i],S9); |
|||
move(s8[1],pS[0],j); |
|||
j := length(s9); |
|||
move(s9[1],pS[0],j); |
|||
k := j; |
k := j; |
||
dec(i); |
dec(i); |
||
If i >= 0 then |
If i >= 0 then |
||
repeat |
repeat |
||
m := MUL[i]; |
|||
d := m div 10000; |
|||
m := m-10000*d; |
|||
move(StrDec4Dgts[d][1],pS[k],4); |
|||
//move to the right place, leading '0' is already there |
|||
move( |
move(StrDec4Dgts[m][1],pS[k+4],4); |
||
inc(k,calcDigits); |
|||
dec(i); |
dec(i); |
||
until i<0; |
until i<0; |
||
Line 1,050: | Line 1,083: | ||
function CheckOneString(const s:Ansistring;pow:NativeInt):NativeInt; |
function CheckOneString(const s:Ansistring;pow:NativeInt):NativeInt; |
||
//check every possible number from one to DIGITS digits, |
//check every possible number from one to DIGITS digits, |
||
//if it is still missing in the list |
//if it is still missing in the list |
||
var |
var |
||
Line 1,073: | Line 1,106: | ||
str_Found[num].foundStr:= cs; |
str_Found[num].foundStr:= cs; |
||
inc(result); |
inc(result); |
||
if num = |
if num =FirstMissing then |
||
while str_Found[FirstMissing].foundIndex <> 0 do |
while str_Found[FirstMissing].foundIndex <> 0 do |
||
inc(FirstMissing); |
inc(FirstMissing); |
||
Line 1,086: | Line 1,119: | ||
Begin |
Begin |
||
T0 := GetTickCount64; |
T0 := GetTickCount64; |
||
number := 6; |
number := 6; |
||
decLimit := 1; |
decLimit := 1; |
||
For i := 1 to digits do |
For i := 1 to digits do |
||
decLimit *= 10; |
decLimit *= 10; |
||
setlength(Str_Found,decLimit); |
setlength(Str_Found,decLimit); |
||
FirstMissing := 0; |
|||
Init_StrDec4Dgts; |
|||
Init_Mul(number); |
Init_Mul(number); |
||
toggle := 0; |
toggle := 0; |
||
found := 0; |
found := 0; |
||
FirstMissing := 0; |
|||
MaxMulIdx := 0; |
MaxMulIdx := 0; |
||
For j := 0 to POT_LIMIT do |
For j := 0 to POT_LIMIT do |
||
Line 1,101: | Line 1,135: | ||
ConvToStr(Pot_N_str,PotArrN[toggle],MaxMulIdx); |
ConvToStr(Pot_N_str,PotArrN[toggle],MaxMulIdx); |
||
inc(found,CheckOneString(Pot_N_str,j)); |
inc(found,CheckOneString(Pot_N_str,j)); |
||
MaxMulIdx := |
MaxMulIdx := Mul_6(PotArrN[toggle],PotArrN[1-toggle],MaxMulIdx); |
||
toggle := 1-toggle; |
toggle := 1-toggle; |
||
if |
if FirstMissing = decLimit then |
||
Begin |
Begin |
||
writeln(#10,'Max power ',j); |
writeln(#10,'Max power ',j); |
||
break; |
break; |
||
end; |
end; |
||
// show me, that the program still runs |
|||
if (j and 1023) = 0 then |
if (j and 1023) = 0 then |
||
write(j:10,found:10, |
write(#13,j:10,found:10,FirstMissing:10); |
||
end; |
end; |
||
writeln(#10,'Found: ',found,' Time used ',(GetTickCount64-T0)/1000:8:3,' secs'); |
writeln(#13#10,'Found: ',found,' Time used ',(GetTickCount64-T0)/1000:8:3,' secs'); |
||
For i := 0 to 22 do//decLimit-1 do |
For i := 0 to 22 do//decLimit-1 do |
||
with Str_Found[i] do |
with Str_Found[i] do |
||
writeln(i:10,' ',number,'^',foundIndex-1:5,' ',foundStr); |
|||
writeln(i:10,' ',number,'^',foundIndex-1:5,' ',foundStr); |
|||
readln; |
|||
end.</syntaxhighlight> |
end.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
TIO.RUN output |
TIO.RUN output |
||
// |
// Power found first missing |
||
0 1 0 |
0 1 0 |
||
1024 751817 10020 |
1024 751817 10020 |
||
Line 1,147: | Line 1,180: | ||
Max power 21798 |
Max power 21798 |
||
Found: 10000000 Time used |
Found: 10000000 Time used 13.717 secs |
||
0 6^ 9 10,077,696 |
0 6^ 9 10,077,696 |
||
1 6^ 0 1 |
1 6^ 0 1 |
||
Line 1,172: | Line 1,205: | ||
22 6^ 22 131,621,703,842,267,136 |
22 6^ 22 131,621,703,842,267,136 |
||
Real time: 14.350 s User time: 13.900 s Sys. time: 0.268 s CPU share: 98.74 % |
|||
Real time: 15.373 s |
|||
</pre> |
|||
User time: 14.953 s |
|||
Sys. time: 0.254 s |
|||
CPU share: 98.92 %</pre> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |