Anonymous user
Smallest power of 6 whose decimal expansion contains n: Difference between revisions
Smallest power of 6 whose decimal expansion contains n (view source)
Revision as of 06:29, 11 April 2021
, 3 years ago→{{header|Pascal}}: searching for strings changed to Phix version.
Not a robot (talk | contribs) (Add Python) |
(→{{header|Pascal}}: searching for strings changed to Phix version.) |
||
Line 350:
=={{header|Pascal}}==
{{Works with|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.
<lang pascal>program PotOf6;
//First occurence of a numberstring with max DIGTIS digits in 6^n
{$IFDEF FPC}
{$MODE DELPHI}
{$Optimization ON,ALL}
{$ELSE}
{$APPTYPE CONSOLE}
{$ENDIF}
uses
sysutils
const
{ DIGITS = 8;
67584 99999998 46238296
Max power 68479
Found: 100000000 Time used 148.584 secs}
DIGITS = 7;
type
tMulElem = Uint32;
tMul = array of tMulElem;
tpMul = pUint32;
tPotArrN = array[0..1] of tMul;
tFound = record
foundIndex: Uint32;
foundStr :Ansistring;
end;
var
Pot_N_str : AnsiString;
Str_Found : array of tFound;
FirstMissing :NativeInt;
T0 : INt64;
procedure Init_Mul(number:NativeInt);
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
pM1,pM2 : tpMul;
carry,prod : Uint64;
begin
pM1 := @Mul1[0];
pM2 := @Mul2[0];
carry := 0;
result :=0;
repeat
prod := n*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;
function Commatize(const s: AnsiString):AnsiString;
var
fromIdx,toIdx :Int32;
Begin
result := '';
fromIdx := length(s);
toIdx := fromIdx-1;
if toIdx < 3 then
Begin
result := s;
exit;
end;
toIdx := 4*(toIdx DIV 3)+toIdx MOD 3;
inc(toIdx);
setlength(result,toIdx);
repeat
result[toIdx] := s[FromIdx];
result[toIdx-1] := s[FromIdx-1];
result[toIdx-2] := s[FromIdx-2];
result[toIdx-3] := ',';
dec(toIdx,4);
dec(FromIdx,3);
until FromIdx<=3;
while fromIdx>=1 do
Begin
result[toIdx] := s[FromIdx];
dec(toIdx);
dec(fromIdx);
end;
end;
procedure ConvToStr(var s:Ansistring;const Mul:tMul;i:NativeInt);
var
s9: string[9];
pS : pChar;
begin
// i := High(MUL);
j := (i+1)*9;
setlength(s,j+1);
Line 402 ⟶ 479:
until i<0;
setlength(s,k);
end;
function
//check every possible number from one to DIGITS digits,
//if it is still missing in the list
var
begin
For i := 1 to lmt do
Begin
repeat
num := num*10+ Ord(s[k])-Ord('0');
IF (num >= FirstMissing) AND (str_Found[num].foundIndex = 0) then
begin
str_Found[num].foundIndex:= pow+1;
// commatize only once. reference counted string
if cs ='' then
cs := Commatize(s);
str_Found[num].foundStr:= cs;
inc(result);
if num =irstMissing then
while str_Found[FirstMissing].foundIndex <> 0 do
inc(FirstMissing);
end;
inc(k)
until (k>lmt) or (k-i >DIGITS-1);
end;
end;
var
i,j,number,toggle,MaxMulIdx,found,decLimit: Int32;
Begin
T0 := GetTickCount64;
number := 6;//<1e9 no power of 10 ;-)
decLimit := 1;
For i := 1 to digits do
decLimit *= 10;
setlength(Str_Found,decLimit);
Init_Mul(number);
toggle := 0;
found := 0;
FirstMissing := 0;
MaxMulIdx := 0;
For j := 0 to POT_LIMIT do
Begin
ConvToStr(Pot_N_str,PotArrN[toggle],MaxMulIdx);
inc(found,CheckOneString(Pot_N_str,j));
MaxMulIdx := Mul_N(PotArrN[toggle],PotArrN[1-toggle],MaxMulIdx,number);
toggle := 1-toggle;
if found>=decLimit then
Begin
writeln(#10,'Max power ',j);
end;
if (j and 1023) = 0 then
write(j:10,found:10,firstMissing:10,#13);
end;
writeln(#10,'
For i := 0 to 22 do//decLimit-1 do
with Str_Found[i] do
if foundIndex >0 then
writeln(i:10,' ',number,'^',foundIndex-1:5,' ',foundStr);
readln;
end.</lang>
{{out}}
<pre>
TIO.RUN output
//Power found first missing
0
8192 9336696 1000015
10240 9846933 1000088
11264 9935108 1000135
12288 9974783 1000204
13312 9990953 1000204
14336 9997035 1000204
15360 9999102 1000204
16384 9999744 1029358
17408 9999934 1029358
18432 9999978 1029358
19456 9999997 8091358
20480 9999999 8091358
21504 9999999 8091358
Max power 21798
Found: 10000000 Time used 14.882 secs
0 6^ 9 10,077,696
1 6^ 0 1
3 6^ 2 36
4 6^ 6 46,656
5 6^ 6 46,656
6 6^ 1 6
7 6^ 5 7,776
8 6^ 12 2,176,782,336
9 6^ 4 1,296
10 6^ 9 10,077,696
11 6^ 16 2,821,109,907,456
12 6^ 4 1,296
13 6^ 13 13,060,694,016
14 6^ 28 6,140,942,214,464,815,497,216
15 6^ 18 101,559,956,668,416
16 6^ 3 216
17 6^ 10 60,466,176
18 6^ 15 470,184,984,576
19 6^ 21 21,936,950,640,377,856
20 6^ 26 170,581,728,179,578,208,256
21 6^ 3 216
22 6^ 22 131,621,703,842,267,136
Real time: 15.373 s
User time: 14.953 s
Sys. time: 0.254 s
CPU share: 98.92 %</pre>
=={{header|Perl}}==
|