elfkin rules
elfkin rules

Reputation: 51

Recursive to Non recursive, troubling me for awhile now

F(n): 
    if n >= 6:
        F(n/3) 
        F(2*n/3) 
    print n

How would I turn this into a nonrecursive function? ive tried to use two while loops one for the n/3 case and one for the 2*n/3 case but nothing outputs the right things

public static void F2Stack(int n) {
    Stack stack2 = new Stack();
    int current = n;
    int current2 = n;
    while(current >= 6) {
            current = current/3;
            stack2.push(current);
        }
    while(current2 >= 6) {
        current2 = current2*2/3;
        stack2.push(current2/3);
        stack2.push(current2*2/3);
        stack2.push(current2);
    }
    while(!(stack2.isEmpty())){
        System.out.println(stack2.pop());
    }

}

Upvotes: 4

Views: 96

Answers (1)

user5914598
user5914598

Reputation:

Damn Corono Virus Lockdown! it took four or five hours today, but we got something. The hard part was java is not capable to do "go to label" I guess. Only you can do "continue/break label". Anyway hope this helps someone;

 public static void main(String[] args) {

    System.out.println("vvvv 18 recursive vvvv");
    recursive(18);
    System.out.println("vvvv 18 nonrecursive vvvv");
    nonRecursive(18);

    System.out.println("vvvv 25 recursive vvvv");
    recursive(25);
    System.out.println("vvvv 25 nonrecursive vvvv");
    nonRecursive(25);

    System.out.println("vvvv 31 recursive vvvv");
    recursive(25);
    System.out.println("vvvv 31 nonrecursive vvvv");
    nonRecursive(25);



}

static void doJob(int n) {
    System.out.println(n);
}

static void recursive(int number) {
    if (number >= 6) {
        recursive(number/3);
        recursive(2*number/3);
    }
    doJob(number);
} 

static void nonRecursive(int number) {

    // a basic context 
    class Ctx {

        int n, m; 
        boolean bn, bm;

        public Ctx(int num) {
            n = num / 3;
            // do not try m = 2 * n :)
            m = 2 * num / 3;
        }

    };

    // how many times can we change the context?  
    // we will use here a bit math
    int d = 2 * ((int)(Math.log(2 * number)/Math.log(3)) + 1);
    Ctx[] ctx = new Ctx[d];

    // current context
    ctx[0] = new Ctx(number);
    int i = 0;
    while (number >= 6 && ctx[0] != null) {

        // do n/3
        if (ctx[i].n >= 6 && !ctx[i].bn) {
            i++;
            ctx[i] = new Ctx(ctx[i-1].n);
            continue;
        } 

        // we reached as deep as poosible for n/3
        if (!ctx[i].bn) {
            doJob(ctx[i].n);
            ctx[i].bn = true;
        }

        // now do 2*n/3
        if (ctx[i].m >= 6 && !ctx[i].bm) {
            i++;
            ctx[i] = new Ctx(ctx[i-1].m);
            continue;
        } 

        if (!ctx[i].bm) {
            doJob(ctx[i].m);
            ctx[i].bm = true;
        }

        // we are done with this context
        ctx[i] = null;
        if (i > 0) {
            i--;
            if (!ctx[i].bn) {
                doJob(ctx[i].n);
                ctx[i].bn = true;
            } else if (!ctx[i].bm) {
                doJob(ctx[i].m);
                ctx[i].bm = true;
            }
        }

    }

    doJob(number);

}

Upvotes: 2

Related Questions