2

My task was to add a bunch of print statements to display the the complete output of Tower of Hanoi to see and understand what it is doing behind the scenes, instead of just giving you the final result.

class TowersApp {
    static int nDisks = 3;
    public static void main(String[] args) {


        doTowers(nDisks, 'A', 'B', 'C');
    }

    public static void doTowers(int topN, char from, char inter, char to) {
        int i = 0;

        if(topN==1) {
            System.out.println("Enter (" + topN + " disk): " + "s=" + from + ", i=" + inter + ", d=" + to);
            System.out.println("Base case: move disk " + topN + " from " + from + " to "+ to);
            System.out.println("Return (" + topN + " disk)"); }
        else {
            System.out.println("Enter (" + topN + " disks): " + "s=" + from + ", i=" + inter + ", d=" + to);
            doTowers(topN-1, from, to, inter);
            System.out.println("Move bottom disk " + topN +
                    " from " + from + " to "+ to);
            doTowers(topN-1, inter, from, to);
            System.out.println("Return (" + topN + " disks)");

        }
    }
}

Here's what I have as my output. The only thing I am missing is indentation. I need to have 1 tab for the first level of recursion, 2 tabs for second level of recursion and so on... Here's what I mean:

Current Output:

Enter (3 disks): s=A, i=B, d=C
Enter (2 disks): s=A, i=C, d=B
Enter (1 disk): s=A, i=B, d=C
Base case: move disk 1 from A to C
Return (1 disk)
Move bottom disk 2 from A to B
Enter (1 disk): s=C, i=A, d=B
Base case: move disk 1 from C to B
Return (1 disk)
Return (2 disks)
Move bottom disk 3 from A to C
Enter (2 disks): s=B, i=A, d=C
Enter (1 disk): s=B, i=C, d=A
Base case: move disk 1 from B to A
Return (1 disk)
Move bottom disk 2 from B to C
Enter (1 disk): s=A, i=B, d=C
Base case: move disk 1 from A to C
Return (1 disk)
Return (2 disks)
Return (3 disks)

Desired Output:

Enter (3 disks): s=A, i=B, d=C
    Enter (2 disks): s=A, i=C, d=B
        Enter (1 disk): s=A, i=B, d=C
            Base case: move disk 1 from A to C
        Return (1 disk)
    Move bottom disk 2 from A to B
Enter (1 disk): s=C, i=A, d=B
...................................

Would I need some sort of counter to "count" how many times I've gone into the function? But then, is that even possible with recursion? Perhaps I am over analyzing when there's a much simpler solution to this problem?

Sahat Yalkabov
  • 32,654
  • 43
  • 110
  • 175

4 Answers4

2

A simple way is to add a String parameter named indent to doTowers that would be prepended to all the output. The call from main would pass an empty string, each call within doTowers would add spaces or tabs to that parameter (i.e. doTowers(indent+" ",...)). You'd change each System.out.println(...) to System.out.println(indent+...)

Geoff Reedy
  • 34,891
  • 3
  • 56
  • 79
2

The simplest, although probably inelegant, way is to just pass the recursive depth as an integral argument to your function and increment it with every new level of depth:

public static void doTowers(int topN, char from, char inter, char to, int depth)

....

doTowers(..., depth + 1)
doTowers(..., depth + 1)

Start out with 0 for depth in your main function. Then, just print a \t for every depth.

Wyatt Anderson
  • 9,612
  • 1
  • 22
  • 25
  • This is a really stupid question, but how would I print \t for depth=1, \t\t for depth=2, \t\t\t for depth=3? – Sahat Yalkabov Nov 22 '10 at 16:29
  • My Java's not super strong, so there are probably more efficient ways to do it, but you could use a `StringBuilder`: `StringBuilder sb; for (int i = 0; i < depth; i++) sb.append('\t');` Then, calling `toString()` on `sb` will give you your sequence of tabs. There are some downsides to this, though... you'd build the sequence every time. Maybe make the `sb` object static and clear it every time? Would be good to hear from a Java guy on this. – Wyatt Anderson Nov 22 '10 at 17:12
1

Sure, a counter solves this nicely. How do you get it along the recursion? Simple, pass it as a parameter!

R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
1

Why not pass in an additional parameter which you increment with each recursive call?

public static void doTowers(int topN, char from, char inter, char to, int depth)

and later on

doTowers(topN-1, from, to, inter, depth+1);

The depth will show you how many tabs to use. First call will be with a 0 depth.

Ioan Alexandru Cucu
  • 11,981
  • 6
  • 37
  • 39