So this is a variation of the tower of hanoi problem. The difference here is that you can only move a ring to the pole on the right (3 poles) and if you are on the 3rd pole, moving right means you end up on the first pole. So for example, if you only have one ring in pole 1 and if you want to move it to pole 3, you must first move the ring to pole 2, then to pole 3. Now a very simple recursive algorithm (in pseudocode) to solve this is the following:
// moving from pole A to pole B
SpecialTowerOfHanoi(n, A, B, C):
if (n == 1):
move ring from A to B
else:
// move the top n-1 to poll B
SpecialTowerOfHanoi(n-1, A, B, C);
// move the top n-1 from poll B to poll C
SpecialTowerOfHanoi(n-1, B, C, A);
move remaining ring from A to B
// move n-1 from poll C to poll A
SpecialTowerOfHanoi(n-1, C, A, B);
// move n-1 from poll A to poll B
SpecialTowerOfHanoi(n-1, A, B, C);
However, this is apparently not the most efficient algorithm and the following is supposedly more efficient:
TowerOfHanoiMoveOnceToRight(n, A, B, C):
if (n == 1):
move ring from A to B
else:
// use a new function to move two times to the right from A to C
TowerOfHanoiMoveTwiceToRight(n-1, A, C, B);
move remaining ring from A to B
// move n-1 from C to B
TowerOfHanoiMoveTwiceToRight(n-1, C, B, A);
TowerOfHanoiMoveTwiceToRight(n, A, C, B):
if (n == 1):
move ring from A to B
move ring from B to C
else:
// move n-1 from A to C
TowerOfHanoiMoveTwiceToRight(n-1, A, C, B);
move remaining ring from A to B
// now only move n-1 from C to A (so once only)
TowerOfHanoiMoveOnceToRight(n-1, C, A, B);
move remaining ring from B to C
// now move n-1 from A to C
TowerOfHanoiMoveTwiceToRight(n-1, A, C, B);
Obviously, you can show that the second way of doing it is more efficient than the first way through some pretty tedious analysis. However, I am sort of stuck conceptually on why the second one is more efficient. The way I think about this is you want to move the bottom piece as quickly as possible and you can only do this once the top n-1 have been moved twice. Hence, by creating a new function, the first function (TowerOfHanoiMoveOnceToRight) looks a lot simpler than the SpecialTowerOfHanoi function. But the TowerOfHanoiMoveTwiceToRight just looks a lot more complicated. I would like to have some insights on how to think of this problem.