Pages

Towers of Hanoi

public class TowersOfHanoi
{
    /**
     * Returns a list of moves that will transfer some number of disks
     * from one peg to another peg while obeying the rules of a popular
     * variation of the Towers of Hanoi puzzle.
     *
     * @param fromPeg  an integer in the set {0, 1, 2}.
     * @param toPeg    an integer in the set {0, 1, 2}.
     * @param numDisks an integer greater than zero.
     */
    public static List getMoves(int fromPeg, int toPeg, int numDisks)
    {
        List moves = new List();
        if (numDisks == 1)
        {
            Move move = new Move(fromPeg, toPeg);
            moves.append(new Node(move));
        }
        else // numDisks > 1
        {
            int otherPeg = 3 - fromPeg - toPeg;
            List moves1 = getMoves(fromPeg, otherPeg, numDisks - 1);
            List moves2 = getMoves(fromPeg, toPeg, 1);
            List moves3 = getMoves(otherPeg, toPeg, numDisks - 1);
            return moves1.add(moves2).add(moves3);
        }
        return moves;
    }
    public static void main(String[] args)
    {
        int fromPeg = Integer.parseInt(args[0]);
        int toPeg = Integer.parseInt(args[1]);
        int numDisks = Integer.parseInt(args[2]);

        int moveNum = 0;
        List moves = getMoves(fromPeg, toPeg, numDisks);
        for (Node n = moves.head; n != null; n = n.next)
        {
            Move move = (Move) n.value;
            String s = ++moveNum + ". Move the top disk from peg ";
            s += move.fromPeg + " to peg " + move.toPeg + ".";
            System.out.println(s);
        }
    }
}

class Move
{
    public final int fromPeg;
    public final int toPeg;    
    public Move(int fromPeg, int toPeg)
    {
        this.fromPeg = fromPeg;
        this.toPeg = toPeg;
    }
}

class Node
{
    public final Object value;
    public Node next = null;    
    public Node(Object value)
    {
        this.value = value;
    }
}

class List
{
    public Node head = null;
    public Node tail = null;    
    public List append(Node node)
    {
        if (tail == null)
        {
            head = tail = node;
        }
        else
        {
            tail.next = node;
            tail = node;
        }
        return this;
    }
    public List add(List list)
    {
        this.append(list.head);
        this.tail = list.tail;
        return this;
    }
}