javaalgorithmrecursiontowers-of-hanoi

Solving tower of Hanoi with given arrangements


I am given an arrangement of valid tower of Hanoi disks. The arrangement is given as an array.

For example [2,2,0]: the indices of the array are the identifiers of the disks, ordered from small to large, and the values of the array are the positions of the corresponding disks (positions are always 0, 1 or 2). In the case of [2,2,0], the smallest two disks are at the third pole, while the largest disk is at the first pole:

      |           |           |
      |           |          [0]
   [22222]        |         [111] 
  ----+----   ----+----   ----+----

Another example: [0,2,1]

      |           |           |
      |           |           |
     [0]       [22222]      [111] 
  ----+----   ----+----   ----+----

Would it be possible to solve the problem recursively for the remaining steps required to move all disks to the target pole (second pole)?

public int solveForSteps(int[] disks){
    // Is there a possible way to solve with given arrangements?
}

Solution

  • I do not have a recursive solution for you. When you look at the usual recursive algorithm for Tower of Hanoi, the actual states can occur deep within the recursion tree, and if you would imagine that such a state is passed to your function, then to further solve the problem from that state requires not only a recursive call, but also rebuilding the stack of "outer" recursive calls. This seems to make it quite complex.

    But you can do it iteratively. Here is one way to do it:

    static void solveForSteps(int[] disks) {
        int n = disks.length;
        // Calculate the next target rod for each of the disks
        int target = 2; // The biggest disk should go to the rightmost rod
        int[] targets = new int[n];
        for (int i = n - 1; i >= 0; i--) {
            targets[i] = target;
            if (disks[i] != target) {
                // To allow for this move, the smaller disk needs to get out of the way
                target = 3 - target - disks[i];
            }
        }
        int i = 0;
        while (i < n) { // Not yet solved?
            // Find the disk that should move
            for (i = 0; i < n; i++) {
                if (targets[i] != disks[i]) { // Found it
                    target = targets[i]; // This and smaller disks should pile up here 
                    System.out.format("move disk %d from rod %d to %d.\n", i, disks[i], target);
                    disks[i] = target; // Make move
                    // Update the next targets of the smaller disks
                    for (int j = i - 1; j >= 0; j--) {
                        targets[j] = target;
                        target = 3 - target - disks[j];
                    }
                    break;
                }
            }
        }
    }
    

    This will print the remaining moves that are necessary to move all disks to the rightmost pole. If instead you want to target the centre pole, then just change int target = 2 to int target = 1.