0

I have a simple class that computes and ultimately prints all possible combinations of X amount of 6-sided die, using recursive enumeration with a process function. However, while this program works (using found algorithms for the enumeration process), I'm not entirely certain what exactly the recursion is doing that allows the class to sort through ALL possibilities.

The main method is calling the enumeration directly,

enumerate(N, 0, new int[N]);

The enumeration method is quite straightforward,

    public static void enumerate(int N, int k, int[] a) {
    if (k == N) {
        process(a);
        return;
    }
    for (int i = 0; i < 2; i++) {
        a[k] = i;
        enumerate(N, k + 1, a);
    }
}

The process method that is called effectively does nothing at this point, and just prints the array that's passed to it

    public static void process(int[] a) {
    for (int i : a) {
        System.out.print(i);
    }
    System.out.println();
}

TL;DR - I have an enumerate method that seemingly returns when k==n - that is, a complete array of possibilities is complete. However, the class returns all possible combinations. What exactly is the recursive function doing that allows this to be possible? Why doesn't the program stop when the enumerate method is returned after forming a complete combination?

HunterM267
  • 199
  • 1
  • 12
  • Do you understand any other recursive programming? – PM 77-1 Jan 30 '18 at 18:08
  • @PM77-1 I have worked with recursive programming in Python primarily in the past, but where I find the most confusion is in the implementation of the recursive call _within_ the for loop. – HunterM267 Jan 30 '18 at 18:20
  • 1
    [This might help](https://stackoverflow.com/questions/9170678/understanding-and-visualizing-recursion) to visualize what's going on. – Andrew S Jan 30 '18 at 18:44
  • Thank you all for the assistance - I was missing the fact that this is essentially a branched tree of recursion, rather than a linear/straight recursion. – HunterM267 Jan 30 '18 at 19:06

1 Answers1

2

The type of recursion you see in this programme reminds me of a binary tree.

If you observe the values of the variables k and i and follow its values during the execution of the programme with a debugger, you can build a binary tree. If we consider the expression (k, i) you can see that the execution of this piece of code creates this recursion tree below:

int[] a = new int[3];
enumerate(a.length, 0, a);

This is the resulting tree with the values (k, i):

                      (0, 0)
         (1, 0)                      (1, 1)
    (2, 0)    (2, 1)             (2, 0)   (2, 1)
(3, 0) (3, 1) (3, 0) (3, 1) (3, 0) (3, 1) (3, 0) (3, 1)  

If you then traverse the tree using depth first search from the (1, 0) and (1, 1) nodes you can reconstruct the values which are printed out by gathering down the traversal path the values of i.

The traversal result using DFS is exactly the result which should be printed out on the console:

000 - (1, 0)(2, 0)(3, 0)
001 - (1, 0)(2, 0)(3, 1)
010 - (1, 0)(2, 1)(3, 0)
011 - (1, 0)(2, 1)(3, 1)
100 - (1, 1)(2, 0)(3, 0)
101 - (1, 1)(2, 0)(3, 1)
110 - (1, 1)(2, 1)(3, 0)
111 - (1, 1)(2, 1)(3, 1)
gil.fernandes
  • 12,978
  • 5
  • 63
  • 76
  • Great, this really helps to clear it up, thank you very much! The only lingering question I really have is - as we've seen, this enumeration algorithm is initiated with a k value of 0. To start forming new array pairs, wouldn't the K value need to be reset to 0? – HunterM267 Jan 30 '18 at 19:12
  • 1
    During recursion the value of the initial `k` is not changed. It stays `0` then a new `k` is created in this line: `enumerate(N, k + 1, a)` and added to the stack. As soon as all frames go off the stack and you come back to the first level of the tree you will find in that initial stack frame a `k` variable with value `0`. – gil.fernandes Jan 30 '18 at 19:17