再帰使わないで強引にやってみました。
といっても再帰使ったのと同じ考え方ですが…
ネタ元 →有名な、あまりに有名な
→ 開発記その13
///
/// 変数の中身を入れ替える
///
public static void Swap(ref T x, ref T y)
{
T temp = y;
y = x;
x = temp;
}
///
/// 作業状態
///
public enum WorkState {
//処理開始
Starting = 0,
//対象の円盤の移動
Moving = 1,
//下の大きい円盤の処理に戻る
Returning = 2
}
///
/// 手順を表示する
///
public static void Move2(int N, char from, char via, char to)
{
if (N <= 0) { return; }
WorkState[] state = new WorkState[N];
state[0] = WorkState.Starting;
int Disk = N;//処理したい円盤
int count = 0;
do
{
if (state[N - Disk] == WorkState.Moving || Disk == 1)
{
//円盤を移動する
Console.WriteLine("{3,5} : 円盤{0} を{1} から{2} へ", Disk, from, to, ++count);
}
if (Disk == 1)
{
//戻る
state[N - Disk] = WorkState.Returning;
}
if (state[N - Disk] == WorkState.Starting
|| state[N - Disk] == WorkState.Returning
&& state[N - Disk - 1] == WorkState.Starting)
{
//作業用の棒と移し先の棒を入れ替える
Swap<char>(ref to, ref via);
}
else
{
//作業用の棒と移し元の棒を入れ替える
Swap<char>(ref from, ref via);
}
if (state[N - Disk] == WorkState.Returning)
{
//下の大きい円盤の処理に戻る
Disk++;
//状態を次に移す
state[N - Disk]++;
}
else {
//上の小さい円盤を処理対象にする
Disk--;
state[N - Disk] = WorkState.Starting;
}
} while (Disk < N || state[0] != WorkState.Returning);
}
やっぱ再帰使わないとわかりにくいですね…
でもN=8あたりからは再帰のより速いかも。 ←遅かったです…
やっぱりHanoiの塔は再帰との相性がいいですね。