Smallest power of 6 whose decimal expansion contains n

From Rosetta Code
Revision as of 22:15, 9 April 2021 by Not a robot (talk | contribs) (Add C)
Smallest power of 6 whose decimal expansion contains n is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task

Show the smallest (non-negative integer) power of   6   whose decimal expansion contains   n,     where   n   <   22


C

<lang C>#include <stdio.h>

  1. include <string.h>
  2. include <gmp.h>

char *power_of_six(unsigned int n, char *buf) {

   mpz_t p;
   mpz_init(p);
   mpz_ui_pow_ui(p, 6, n);
   mpz_get_str(buf, 10, p);
   mpz_clear(p);
   return buf;

}

char *smallest_six(unsigned int n) {

   static char nbuf[32], powbuf[1024];
   unsigned int p = 0;
   
   do {
       sprintf(nbuf, "%u", n);
       power_of_six(p++, powbuf);
   } while (!strstr(powbuf, nbuf));
   
   return powbuf;

}

int main() {

   unsigned int i;
   
   for (i=0; i<22; i++) {
       printf("%d: %s\n", i, smallest_six(i));
   }
   
   return 0;

}</lang>

Output:
0: 10077696
1: 1
2: 216
3: 36
4: 46656
5: 46656
6: 6
7: 7776
8: 2176782336
9: 1296
10: 10077696
11: 2821109907456
12: 1296
13: 13060694016
14: 6140942214464815497216
15: 101559956668416
16: 216
17: 60466176
18: 470184984576
19: 21936950640377856
20: 170581728179578208256
21: 216

F#

<lang fsharp> // Nigel Galloway. April 9th., 2021 let rec fN i g e l=match l%i=g,l/10I with (true,_)->e |(_,l) when l=0I->fN i g (e*6I) (e*6I) |(_,l)->fN i g e l [0I..99I]|>Seq.iter(fun n->printfn "%2d %A" (int n)(fN(if n>9I then 100I else 10I) n 1I 1I)) </lang>

Output:
 0 10077696
 1 1
 2 216
 3 36
 4 46656
 5 46656
 6 6
 7 7776
 8 2176782336
 9 1296
10 10077696
11 2821109907456
12 1296
13 13060694016
14 6140942214464815497216
15 101559956668416
16 216
17 60466176
18 470184984576
19 21936950640377856
20 170581728179578208256
21 216
22 131621703842267136
23 2176782336
24 1023490369077469249536
25 170581728179578208256
26 16926659444736
27 279936
28 2821109907456
29 1296
30 13060694016
31 131621703842267136
32 4738381338321616896
33 2176782336
34 1023490369077469249536
35 609359740010496
36 36
37 21936950640377856
38 131621703842267136
39 221073919720733357899776
40 13060694016
41 78364164096
42 131621703842267136
43 28430288029929701376
44 16926659444736
45 470184984576
46 46656
47 470184984576
48 6140942214464815497216
49 470184984576
50 21936950640377856
51 1326443518324400147398656
52 623673825204293256669089197883129856
53 789730223053602816
54 6140942214464815497216
55 101559956668416
56 46656
57 470184984576
58 3656158440062976
59 16926659444736
60 60466176
61 1679616
62 362797056
63 47751966659678405306351616
64 78364164096
65 46656
66 46656
67 1679616
68 101559956668416
69 10077696
70 362797056
71 131621703842267136
72 170581728179578208256
73 16926659444736
74 2821109907456
75 47751966659678405306351616
76 7776
77 7776
78 2176782336
79 279936
80 28430288029929701376
81 789730223053602816
82 2176782336
83 78364164096
84 470184984576
85 21936950640377856
86 36845653286788892983296
87 61886548790943213277031694336
88 28430288029929701376
89 789730223053602816
90 2821109907456
91 221073919720733357899776
92 16926659444736
93 279936
94 13060694016
95 101559956668416
96 1296
97 362797056
98 470184984576
99 279936
Real: 00:00:00.066

Factor

Works with: Factor version 0.99 2021-02-05

<lang factor>USING: formatting kernel lists lists.lazy math math.functions present sequences tools.memory.private ;

powers-of-6 ( -- list )
   0 lfrom [ 6 swap ^ ] lmap-lazy ;
smallest ( m -- n )
   present powers-of-6 [ present subseq? ] with lfilter car ;

22 [ dup smallest commas "%2d %s\n" printf ] each-integer</lang>

Output:
 0   10,077,696
 1   1
 2   216
 3   36
 4   46,656
 5   46,656
 6   6
 7   7,776
 8   2,176,782,336
 9   1,296
10   10,077,696
11   2,821,109,907,456
12   1,296
13   13,060,694,016
14   6,140,942,214,464,815,497,216
15   101,559,956,668,416
16   216
17   60,466,176
18   470,184,984,576
19   21,936,950,640,377,856
20   170,581,728,179,578,208,256
21   216

Haskell

<lang haskell>import Control.Monad import Data.List import Text.Printf

sixes :: [Integer] sixes = iterate (*6) 1

smallest :: Integer -> Integer smallest n = head $ filter (\r -> show n `isInfixOf` show r) sixes

main :: IO () main = putStr $ concatMap (printf "%2d: %d\n" `ap` smallest) [0..21]</lang>

Output:
 0: 10077696
 1: 1
 2: 216
 3: 36
 4: 46656
 5: 46656
 6: 6
 7: 7776
 8: 2176782336
 9: 1296
10: 10077696
11: 2821109907456
12: 1296
13: 13060694016
14: 6140942214464815497216
15: 101559956668416
16: 216
17: 60466176
18: 470184984576
19: 21936950640377856
20: 170581728179578208256
21: 216

Julia

<lang julia>using Formatting

digcontains(n, dig) = contains(String(Char.(digits(n))), String(Char.(dig)))

function findpow6containing(needle)

   dig = digits(needle)
   for i in 0:1000
       p = big"6"^i
       digcontains(p, dig) && return p
   end
   error("could not find a  power of 6 containing $dig")

end

for n in 0:21

   println(rpad(n, 5), format(findpow6containing(n), commas=true))

end

</lang>

Output:
0    10,077,696
1    1
2    216
3    36
4    46,656
5    46,656
6    6
7    7,776
8    2,176,782,336
9    1,296
10   10,077,696
11   2,821,109,907,456
12   1,296
13   13,060,694,016
14   6,140,942,214,464,815,497,216
15   101,559,956,668,416
16   216
17   60,466,176
18   470,184,984,576
19   21,936,950,640,377,856
20   170,581,728,179,578,208,256
21   216

Pascal

Works with: Free Pascal

Doing long multiplikation like in primorial task. <lang pascal>program PotOf6; {$IFDEF FPC} {$MODE DELPHI} {$ENDIF} uses

 sysutils,strutils;

const // POT_LIMIT = 6260;DEC_LIMIT = 1000000;//'575115' in 6^6260 // POT_LIMIT = 1736;DEC_LIMIT = 100000;

   //'83081' in 6^1736 mean power   422.48

// POT_LIMIT = 444; DEC_LIMIT = 10000;

   //'2565'   mean power   135.82  0.157s

// POT_LIMIT = 147; DEC_LIMIT = 1000;

   //'120'      mean power    44.21

// POT_LIMIT = 46; DEC_LIMIT = 100;

   //'52'   mean power    15.71
 POT_LIMIT = 28;DEC_LIMIT =       22;
   //'14'   mean power     9.73

type

 tMulElem = Uint32;
 tMul = array of tMulElem;

var

 Pot_N_str : array of AnsiString;
 T0,maxPow,PowerSum,lastpot,SumLenght : INt64;

procedure ConvToStr(var s:Ansistring;const Mul:tMul); var

 s9: string[9];
 pS : pChar;
 i,j,k : NativeInt;

begin

 i := High(MUL);
 j := (i+1)*9;
 setlength(s,j+1);
 pS := pChar(s);
 // fill complete with '0'
 fillchar(pS[0],j,'0');
 str(Mul[i],S9);
 j := length(s9);
 move(s9[1],pS[0],j);
 k := j;
 dec(i);
 If i >= 0 then
   repeat
     str(Mul[i],S9);// no leading '0'
     j := length(s9);
     inc(k,9);
     //move to the right place, leading '0' is already there
     move(s9[1],pS[k-j],j);
     dec(i);
   until i<0;
 setlength(s,k);
 inc(SumLenght,k);

end;

function Mul_N(var Mul:tMul;n:Uint64):tMul; //n<LongWordDec ! const

 LongWordDec = 1000*1000*1000;

var

 prod,carry : Uint64;
 j : NativeInt;

begin

 Setlength(result,length(Mul)+1);
 carry := 0;
 For j := 0 to High(Mul) do
 Begin
   prod  := n*Mul[j]+Carry;
   Carry := prod Div LongWordDec;
   result[j] := Prod - Carry*LongWordDec;
 end;
 IF Carry <> 0 then
   result[High(Mul)+1] := Carry
 else
   Setlength(result,length(Mul));

end;

procedure OutS(const s:Ansistring;j:nativeInt); begin

 writeln(s,'  ',j);

end;

procedure GeneratePot_N_Str(number:NativeInt); var

 PotArrN : array[0..1] of tMul;
 i,toggle : NativeInt;

Begin

 setlength(Pot_N_str,POT_LIMIT+1);
 Pot_N_str[0] := '1';
 Pot_N_str[1] := IntToStr(number);
 setlength(PotArrN[0],1);
 setlength(PotArrN[1],1);
 PotArrN[0,0] := 1;
 PotArrN[1,0] := number;

//create all pot of numbers up to number**POT_LIMIT with clean up in parallel

 SumLenght   :=0;
 i := 2;
 toggle := 0;
 while i <= POT_LIMIT do
 begin
   PotArrN[toggle] := Mul_N(PotArrN[1-toggle],number);
   ConvToStr(Pot_N_str[i],PotArrN[toggle]);
   toggle := 1-toggle;
   inc(i);
 end;
 writeln(' used by strings ',Numb2USA(IntToStr(SumLenght)),' bytes');

end; procedure OutT(const s: Ansistring;j:NativeInt); Begin

 writeln(j:10,maxPow/(j+1):8:2,(maxPow-lastPot)/1024:8:2,(GetTickCount64-T0)/1000:10:3);
 T0 := GetTickCount64;
 lastpot := maxPow;

end; var

 s: ansistring;
 i,j,number: Int32;

Begin

 number := 6;
 T0 := GetTickCount64;
 GeneratePot_N_Str(number);
 writeln('Generating time to power limit ',(GetTickCount64-T0)/1000:5:3,'s');
 T0 := GetTickCount64;
 maxPow := 0;
 lastpot := 0;
 For i := 0 to DEC_LIMIT-1 do
 begin
   str(i,s);
   For j := 0 to POT_LIMIT do
   Begin
     if Pos(s,Pot_N_str[j])>0 then
     Begin
       IF maxPow<j then
         maxPow := J;
       PowerSum +=j;
       IF POT_Limit > 99 then
         write(s:3,number:3,'^',j:5,maxPow:6,#13)
       else
         writeln(s:3,number:3,'^',j:2,'  ', Pot_N_str[j]);
       break;
     end;
   end;
 end;
 writeln;
 writeln('mean power to find string',PowerSum/DEC_LIMIT:8:2);

end.</lang>

Output:
 used by strings 330
Generating time to power limit 0.000s
  0  6^ 9  10077696
  1  6^ 0  1
  2  6^ 3  216
  3  6^ 2  36
  4  6^ 6  46656
  5  6^ 6  46656
  6  6^ 1  6
  7  6^ 5  7776
  8  6^12  2176782336
  9  6^ 4  1296
 10  6^ 9  10077696
 11  6^16  2821109907456
 12  6^ 4  1296
 13  6^13  13060694016
 14  6^28  6140942214464815497216
 15  6^18  101559956668416
 16  6^ 3  216
 17  6^10  60466176
 18  6^15  470184984576
 19  6^21  21936950640377856
 20  6^26  170581728179578208256
 21  6^ 3  216

mean power to find string    9.73

//Search strings 0 to 99999
  used by strings 1,174,099 bytes
Generating time to power limit 0.008s
99999  6^ 1287  1736
mean power to find string  422.48

real	0m14,684s
user	0m14,522s

Perl

<lang perl>use strict; use warnings; use List::Util 'first'; use Math::AnyNum ':overload';

sub comma { reverse ((reverse shift) =~ s/(.{3})/$1,/gr) =~ s/^,//r }

for my $n (0..21, 314159) {

   my $e = first { 6**$_ =~ /$n/ } 0..1000;
   printf "%7d:  6^%-3s  %s\n", $n, $e, comma 6**$e;

}</lang>

Output:
      0:  6^9    10,077,696
      1:  6^0    1
      2:  6^3    216
      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
 314159:  6^494  2,551,042,473,957,557,281,758,472,595,966,885,638,262,058,644,568,332,160,010,313,393,465,384,231,415,969,801,503,269,402,221,368,959,426,761,447,049,526,922,498,341,120,174,041,236,629,812,681,424,262,988,020,546,286,492,213,224,906,594,147,652,459,693,833,191,626,748,973,370,777,591,205,509,673,825,541,899,874,436,305,798,094,943,728,762,682,333,192,202,041,960,669,401,031,964,634,164,426,985,990,195,192,836,400,994,016,666,910,919,499,884,972,133,471,176,804,190,463,444,807,178,864,658,551,422,631,018,496

Phix

Another good opportunity to do some string math, this time with embedded commas. Scales effortlessly.
(Related recent task: Show_the_(decimal)_value_of_a_number_of_1s_appended_with_a_3,_then_squared#Phix)

constant lim = 22           -- (tested to 10,000,000)
atom t0 = time(), t1 = t0+1
sequence res = repeat(0,lim),
         pwr = repeat(0,lim)
string p6 = "1"
res[2] = p6
integer found = 1, p = 0
while found<lim do
    integer carry = 0
    for i=length(p6) to 1 by -1 do
        if p6[i]!=',' then
            integer digit = (p6[i]-'0')*6+carry
            p6[i] = remainder(digit,10)+'0'
            carry = floor(digit/10)
        end if
    end for
    if carry then
        if remainder(length(p6)+1,4)=0 then
            p6 = "," & p6
        end if
        p6 = carry+'0' & p6
    end if
    p += 1
    for i=1 to length(p6) do
        if p6[i]!=',' then
            integer digit = 0, j = i
            while j<=length(p6) and digit<=lim do
                j += p6[j]=','
                digit = digit*10+p6[j]-'0'
                if digit<lim and res[digit+1]=0 then
                    res[digit+1] = p6
                    pwr[digit+1] = p
                    found += 1
                end if
                j += 1
            end while
        end if
    end for
    if time()>t1 then
        progress("found %,d/%,d, at 6^%,d which has %,d digits (%s)",
                 {found,lim,p,length(p6)*3/4,elapsed(time()-t0)})
        t1 = time()+1
    end if
end while
papply(true,printf,{1,{"%2d  %29s = 6^%d\n"},shorten(columnize({tagset(lim-1,0),res,pwr}),"",10)})
Output:
 0                     10,077,696 = 6^9
 1                              1 = 6^0
 2                            216 = 6^3
 3                             36 = 6^2
 4                         46,656 = 6^6
 5                         46,656 = 6^6
 6                              6 = 6^1
 7                          7,776 = 6^5
 8                  2,176,782,336 = 6^12
 9                          1,296 = 6^4
10                     10,077,696 = 6^9
11              2,821,109,907,456 = 6^16
12                          1,296 = 6^4
13                 13,060,694,016 = 6^13
14  6,140,942,214,464,815,497,216 = 6^28
15            101,559,956,668,416 = 6^18
16                            216 = 6^3
17                     60,466,176 = 6^10
18                470,184,984,576 = 6^15
19         21,936,950,640,377,856 = 6^21
20    170,581,728,179,578,208,256 = 6^26
21                            216 = 6^3

A limit of 10,000,000 takes 1 min 41s, reaches 6^21,798 which has 16,963 digits (not including commas) and is the first to contain 8091358, at offset 13,569.

Raku

<lang perl6>use Lingua::EN::Numbers;

sub super ($n) { $n.trans(<0 1 2 3 4 5 6 7 8 9> => <⁰ ¹ ² ³ ⁴ ⁵ ⁶ ⁷ ⁸ ⁹>) }

my @po6 = ^Inf .map: *.exp: 6;

put join "\n", (flat ^22, 120).map: -> $n {

   sprintf "%3d: 6%-4s %s", $n, .&super, comma @po6[$_]
   given @po6.first: *.contains($n), :k

};</lang>

Output:
  0: 6⁹    10,077,696
  1: 6⁰    1
  2: 6³    216
  3: 6²    36
  4: 6⁶    46,656
  5: 6⁶    46,656
  6: 6¹    6
  7: 6⁵    7,776
  8: 6¹²   2,176,782,336
  9: 6⁴    1,296
 10: 6⁹    10,077,696
 11: 6¹⁶   2,821,109,907,456
 12: 6⁴    1,296
 13: 6¹³   13,060,694,016
 14: 6²⁸   6,140,942,214,464,815,497,216
 15: 6¹⁸   101,559,956,668,416
 16: 6³    216
 17: 6¹⁰   60,466,176
 18: 6¹⁵   470,184,984,576
 19: 6²¹   21,936,950,640,377,856
 20: 6²⁶   170,581,728,179,578,208,256
 21: 6³    216
120: 6¹⁴⁷  2,444,746,349,972,956,194,083,608,044,935,243,159,422,957,210,683,702,349,648,543,934,214,737,968,217,920,868,940,091,707,112,078,529,114,392,164,827,136

REXX

<lang rexx>/*REXX pgm finds the smallest (decimal) power of 6 which contains N, where N < 22. */ numeric digits 100 /*ensure enough decimal digs for 6**N */ parse arg hi . /*obtain optional argument from the CL.*/ if hi== | hi=="," then hi= 22 /*Not specified? Then use the default.*/ w= 50 /*width of a number in any column. */

              @smp6= ' smallest power of  six  (expressed in decimal)  which contains  N'

say ' N │ power │'center(@smp6, 20 + w ) /*display the title of the output. */ say '─────┼───────┼'center("" , 20 + w, '─') /* " " separator " " " */

     do j=0  for hi                             /*look for a power of 6 that contains N*/
                    do p=0;   x= 6**p           /*compute a power of six (in decimal). */
                    if pos(j, x)>0  then leave  /*does the power contain an   N ?      */
                    end   /*p*/
     c= commas(x)                               /*maybe add commas to the powe of six. */
     z= right(c, max(w, length(c) ) )           /*show a power of six, allow biger #s. */
     say center(j, 5)'│'center(p, 7)"│"   z     /*display what we have so far  (cols). */
     end   /*j*/

say '─────┴───────┴'center("" , 20 + w, '─') /* " " separator " " " */ exit 0 /*stick a fork in it, we're all done. */ /*──────────────────────────────────────────────────────────────────────────────────────*/ commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?</lang>

output   when using the default input:
  N  │ power │   smallest power of  six  (expressed in decimal)  which contains  N
─────┼───────┼──────────────────────────────────────────────────────────────────────
  0  │   9   │                                         10,077,696
  1  │   0   │                                                  1
  2  │   3   │                                                216
  3  │   2   │                                                 36
  4  │   6   │                                             46,656
  5  │   6   │                                             46,656
  6  │   1   │                                                  6
  7  │   5   │                                              7,776
  8  │  12   │                                      2,176,782,336
  9  │   4   │                                              1,296
 10  │   9   │                                         10,077,696
 11  │  16   │                                  2,821,109,907,456
 12  │   4   │                                              1,296
 13  │  13   │                                     13,060,694,016
 14  │  28   │                      6,140,942,214,464,815,497,216
 15  │  18   │                                101,559,956,668,416
 16  │   3   │                                                216
 17  │  10   │                                         60,466,176
 18  │  15   │                                    470,184,984,576
 19  │  21   │                             21,936,950,640,377,856
 20  │  26   │                        170,581,728,179,578,208,256
 21  │   3   │                                                216
─────┴───────┴──────────────────────────────────────────────────────────────────────

Ring

<lang ring> load "stdlib.ring"

decimals(0) see "working..." + nl see "Smallest power of 6 whose decimal expansion contains n:" + nl

num = 0 limit = 200

for n = 1 to 21

   strn = string(n)
   for m = 0 to limit
       strpow = string(pow(6,m))
       ind = substr(strpow,strn)
       if ind > 0
          see "" + n + ". " + "6^" + m + " = " + strpow + nl
          exit
       ok
   next

next

see "done..." + nl </lang>

Output:
working...
Smallest power of 6 whose decimal expansion contains n:
1. 6^0 = 1
2. 6^3 = 216
3. 6^2 = 36
4. 6^6 = 46656
5. 6^6 = 46656
6. 6^1 = 6
7. 6^5 = 7776
8. 6^12 = 2176782336
9. 6^4 = 1296
10. 6^9 = 10077696
11. 6^16 = 2821109907456
12. 6^4 = 1296
13. 6^13 = 13060694016
14. 6^28 = 6140942214464815497216
15. 6^18 = 101559956668416
16. 6^3 = 216
17. 6^10 = 60466176
18. 6^15 = 470184984576
19. 6^21 = 21936950640377856
20. 6^26 = 170581728179578208256
21. 6^3 = 216
done...

Wren

Library: Wren-big
Library: Wren-fmt

<lang ecmascript>import "/big" for BigInt import "/fmt" for Fmt

System.print(" n smallest power of 6 which contains n") var six = BigInt.new(6) for (n in 0..21) {

   var i = 0
   while (true) {
       var pow6 = six.pow(i).toString
       if (pow6.contains(n.toString)) {
           Fmt.print("$2d  6^$-2d = $,s", n, i, pow6)
           break
       }
       i = i + 1
   }

}</lang>

Output:
 n  smallest power of 6 which contains n
 0  6^9  = 10,077,696
 1  6^0  = 1
 2  6^3  = 216
 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