The Never Ending Towers of Hanoi |
The Problem
In 1883, Edward Lucas invented, or perhaps reinvented, one of the most popular puzzles of all times - the Tower of Hanoi, as he called it - which is still used today in many computer science textbooks to demonstrate how to write a recursive algorithm or program. First of all, we will make a list of the rules of the puzzle:· There are three pegs: A, B and C.
· There are n disks. The number n is constant while working the puzzle.
· All disks are different in size.
· The disks are initially stacked on peg A so that they increase in size from the top to the bottom.
· The goal of the puzzle is to transfer the entire tower from the A peg to the peg C.
· One disk at a time can be moved from the top of a stack either to an empty peg or to a peg with a larger disk than itself on the top of its stack.
Your job will be to write a program which will show a copy of the puzzle on the screen step by step, as you move the disks around. This program has to solve the problem in an efficient way.
TIP: It is well known and rather easy to prove that the minimum number of moves needed to complete the puzzle with n disks is 2n -1.
The Input
The input file will consist of a series of lines. Each line will contain two integers n, m. n, lying within the range [1,250], will denote the number of disks and m, belonging to [0,2n-1], will be the number of the last move, you may assume that m will also be less than 216, and you may also assume that a good algorithm will always have enough time. The file will end at a line formed by two zeros.The Output
The output will consist again of a series of lines, formatted as show below.NOTES : There are 3 spaces between de ‘=>’ and the first number printed. If there isn't any number, there should be no spaces.
All the disks in a single peg are printed in a single line.
Print a blank line after every problem.
Sample Input
64 28 45
0 0
Problem #1 A=> 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 B=> C=> A=> 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 B=> 1 C=> A=> 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 B=> 1 C=> 2 Problem #2 A=> 8 7 6 5 4 3 2 1 B=> C=> A=> 8 7 6 5 4 3 2 B=> 1 C=> A=> 8 7 6 5 4 3 B=> 1 C=> 2 A=> 8 7 6 5 4 3 B=> C=> 2 1 A=> 8 7 6 5 4 B=> 3 C=> 2 1 A=> 8 7 6 5 4 1 B=> 3 C=> 2 A=> 8 7 6 5 4 1 B=> 3 2 C=> A=> 8 7 6 5 4 B=> 3 2 1 C=> A=> 8 7 6 5 B=> 3 2 1 C=> 4 A=> 8 7 6 5 B=> 3 2 C=> 4 1 A=> 8 7 6 5 2 B=> 3 C=> 4 1 A=> 8 7 6 5 2 1 B=> 3 C=> 4 A=> 8 7 6 5 2 1 B=> C=> 4 3 A=> 8 7 6 5 2 B=> 1 C=> 4 3 A=> 8 7 6 5 B=> 1 C=> 4 3 2 A=> 8 7 6 5 B=> C=> 4 3 2 1 A=> 8 7 6 B=> 5 C=> 4 3 2 1 A=> 8 7 6 1 B=> 5 C=> 4 3 2 A=> 8 7 6 1 B=> 5 2 C=> 4 3 A=> 8 7 6 B=> 5 2 1 C=> 4 3 A=> 8 7 6 3 B=> 5 2 1 C=> 4 A=> 8 7 6 3 B=> 5 2 C=> 4 1 A=> 8 7 6 3 2 B=> 5 C=> 4 1 A=> 8 7 6 3 2 1 B=> 5 C=> 4 A=> 8 7 6 3 2 1 B=> 5 4 C=> A=> 8 7 6 3 2 B=> 5 4 1 C=> A=> 8 7 6 3 B=> 5 4 1 C=> 2 A=> 8 7 6 3 B=> 5 4 C=> 2 1 A=> 8 7 6 B=> 5 4 3 C=> 2 1 A=> 8 7 6 1 B=> 5 4 3 C=> 2 A=> 8 7 6 1 B=> 5 4 3 2 C=> A=> 8 7 6 B=> 5 4 3 2 1 C=> A=> 8 7 B=> 5 4 3 2 1 C=> 6 A=> 8 7 B=> 5 4 3 2 C=> 6 1 A=> 8 7 2 B=> 5 4 3 C=> 6 1 A=> 8 7 2 1 B=> 5 4 3 C=> 6 A=> 8 7 2 1 B=> 5 4 C=> 6 3 A=> 8 7 2 B=> 5 4 1 C=> 6 3 A=> 8 7 B=> 5 4 1 C=> 6 3 2 A=> 8 7 B=> 5 4 C=> 6 3 2 1 A=> 8 7 4 B=> 5 C=> 6 3 2 1 A=> 8 7 4 1 B=> 5 C=> 6 3 2 A=> 8 7 4 1 B=> 5 2 C=> 6 3 A=> 8 7 4 B=> 5 2 1 C=> 6 3 A=> 8 7 4 3 B=> 5 2 1 C=> 6 A=> 8 7 4 3 B=> 5 2 C=> 6 1
import java.io.FileInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.OutputStreamWriter;
import java.io.StreamTokenizer;
public class Main {
private static final boolean DEBUG = false;
private static final int N = 260;
private BufferedReader cin;
private PrintWriter cout;
private StreamTokenizer tokenizer;
private int n, m;
private int[][] pegs;
private int[] size;
private int cnt;
private int cas = 1;
public void init()
{
try {
if (DEBUG) {
cin = new BufferedReader(new InputStreamReader(
new FileInputStream("e:\\uva_in.txt")));
} else {
cin = new BufferedReader(new InputStreamReader(System.in));
}
tokenizer = new StreamTokenizer(cin);
cout = new PrintWriter(new OutputStreamWriter(System.out));
} catch (Exception e) {
e.printStackTrace();
}
}
private String next()
{
try {
tokenizer.nextToken();
if (tokenizer.ttype == StreamTokenizer.TT_EOF) return null;
else if (tokenizer.ttype == StreamTokenizer.TT_NUMBER) {
return String.valueOf((int)tokenizer.nval);
} else return tokenizer.sval;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public boolean input()
{
n = Integer.parseInt(next());
m = Integer.parseInt(next());
if (n == 0 && m == 0) return false;
pegs = new int[3][n];
size = new int[3];
size[0] = n;
size[1] = size[2] = 0;
for (int i = 0; i < size[0]; i++) {
pegs[0][i] = n - i;
}
return true;
}
private void dfs(int n, int a, int b, int c)
{
if (n == 0) return;
if (cnt >= m) return;
dfs(n - 1, a, c, b);
if (cnt >= m) return;
pegs[c][size[c]] = pegs[a][size[a] - 1];
size[c]++;
size[a]--;
for (int i = 0; i < 3; i++) {
int len = size[i];
cout.print((char)('A' + i) + "=>");
for (int j = 0; j < len; j++) {
if (j == 0) cout.print(" ");
else cout.print(" ");
cout.print(pegs[i][j]);
}
cout.println();
}
cout.println();
cout.flush();
if (cnt++ == m) return;
dfs(n - 1, b, a, c);
}
public void solve()
{
cnt = 0;
cout.println("Problem #" + cas++);
cout.println();
for (int i = 0; i < 3; i++) {
int len = size[i];
cout.print((char)('A' + i) + "=>");
for (int j = 0; j < len; j++) {
if (j == 0) cout.print(" ");
else cout.print(" ");
cout.print( pegs[i][j]);
}
cout.println();
}
cout.println();
dfs(n, 0, 1, 2);
}
public static void main(String[] args)
{
Main solver = new Main();
solver.init();
while (solver.input()) {
solver.solve();
}
}
}