views:

184

answers:

1

Can someone hep me find an algorithm for a recursive function func(int k) to return 3^k in only n+1 calls where k is in the range [ 3^n, 3^(n+1) )

For example, the function should return 3^1 or 3^2 in 1 call, 3^3, 3^4, .. 3^8 in 2 calls, 3^9, 3^10 .. in 3 calls and so on.

+5  A: 

Here is the algorithm in untested C/C++:

int 3pow(x)
{
    switch(x)
    {
     case 1: return 3;
     case 2: return 9;
     case 3: return 27;
    }

    int remain  = x % 3,
        recur   = 3pow((x-remain)/3),
        combine = recur * recur * recur;

    switch (remain)
    {
     case 0:  return combine;
     case 1:  return combine * 3;
     default: return combine * 9;
    }
}

(I have not compiled, run, or otherwise tested this code. There may be syntax errors and other bugs. But it's sufficient to get the point across.)

What's different about this algorithm is that it recurses by dividing by 3 instead of 2. This function is rather ugly by necessity, as abstracting away some of the pattern would likely involve more recursion. Still, this algorithm is now O(log3n). Here's a table of a given x from 1-50 and the number of recursive calls required (as a two-element lisp list):

(1  1) (2  1) (3  1) (4  2) (5  2) (6  2) (7  2) (8  2) (9  2) (10 2)
(11 2) (12 3) (13 3) (14 3) (15 3) (16 3) (17 3) (18 3) (19 3) (20 3)
(21 3) (22 3) (23 3) (24 3) (25 3) (26 3) (27 3) (28 3) (29 3) (30 3)
(31 3) (32 3) (33 3) (34 3) (35 3) (36 4) (37 4) (38 4) (39 4) (40 4)
(41 4) (42 4) (43 4) (44 4) (45 4) (46 4) (47 4) (48 4) (49 4) (50 4)
(51 4) (52 4) (53 4) (54 4) (55 4) (56 4) (57 4) (58 4) (59 4) (60 4)
(61 4) (62 4) (63 4) (64 4) (65 4) (66 4) (67 4) (68 4) (69 4) (70 4)
(71 4) (72 4) (73 4) (74 4) (75 4) (76 4) (77 4) (78 4) (79 4) (80 4)
(81 4) (82 4) (83 4) (84 4) (85 4) (86 4) (87 4) (88 4) (89 4) (90 4)
(91 4) (92 4) (93 4) (94 4) (95 4) (96 4) (97 4) (98 4) (99 4) (100 4)

You can see that even as we get up over 100 it only take 4 recursive calls.

Kyle Cronin
shouldn't f(2) be 9?
Jaelebi
indeed - it's a typo
Kyle Cronin
f(2) does not need to be hard coded, it will follow the even rule and get set to f(1) * f(1)
Scott Chamberlain
for f(5), there are three calls, f(5), 3*f(4), f(2)^2. I need that for n=3...8, calls should only be 2.
Jaelebi
Could you post it in c++ or in pseudocode?
Jaelebi