目次
導入:
今日は「ハノイの塔」というとても面白いゲームに出会ったのですが、子供の頃にこのパズルゲームをプレイしたことがなかったので、今日はコードを使ってこのパズルゲームを実現してみます。ハノイの塔のコードを書く前に、まずハノイの塔のゲームルール、ゲームプレイ、ゲームプロセスを理解します。
ハノイの塔としても知られるハノイの塔は、古代インドの伝説に由来する知育玩具です。ブラフマー神が世界を創造したとき、3本のダイヤモンドの柱を作り、1本の柱には64枚の金の円盤を下から上に大きさの順に積み上げました。ブラフマーはバラモンに、別の柱の上にある円盤を下から大きさの順に並べ替えるよう命じました。そして、小さな円盤では円盤を拡大することはできず、3本の柱の間で一度に移動できる円盤は1枚だけであると規定されています。
分析します:
ハノイの 2 つの塔の移行プロセスを分析します。
柱 A に青い四角枠と赤い逆枠の 2 枚のシートがあるとします。これが初期状態です。
元の「大きいものは下に、小さいものは上」のルールに従って、赤と青のボックスをピラー A からピラー C に移行したいと考えています。明らかに、最初に青いボックスをピラー B に移行してから、移行する必要があります。赤いボックスをピラー C に移行し、次に青いボックスをピラー B からピラー C に移行すると、移行が完了します。
毎回ピラーの一番上のボックスを移行すると仮定すると、移行の順序は次のように表すことができます。
A -> B
A -> C
B -> C
これまでのところ、ハノイの 2 つの塔は移転されています。
ハノイの 3 つの塔の移行プロセスを分析します。
3 つのハノイの塔 (赤いボックス、青いボックス、黄色のボックス) を移行するとします。これが初期状態です。
上記の各移行柱の最上部のボックスのルールに従って、シーケンスは次のように表現できます。
A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C
これまでにハノイの 3 つの塔が移転されました。
それでは次に考えるべきは、2 つのハノイ タワーから 3 つのハノイ タワーにどのようなルールを導き出せるのかということです。
ハノイの 3 つの塔の移行プロセスの観点から見ると、最初に必要なことは、一番下のボックスを B ピラーに移行し、一番下の最大のボックスを解放して C ボックスに移行することです。上の 2 つのボックスが、最大のボックスの上に順番に配置されます。つまり、ハノイの塔がいくつあっても、大きな問題を小さな問題に変えることができるのです。
たとえば、ハノイの塔の 4 つの部分を移行する場合、最初に考慮する必要があるのは、下部フレームの上の 3 つの部分を正しく移行し、下部フレームをターゲットの柱に移行する方法です。
次に、ハノイの 3 つの塔を移行するときに考慮しなければならないのは、下部フレームの上の 2 つの部分を正しく移行し、下部フレームをターゲットの柱に移行するかどうかです。
同様に、ハノイの塔を2つ移行するときも、もちろん上のほうを対象の柱以外のB柱に移行し、次に下のフレームを対象の柱に移動し、続けてBピラーのフレームを対象の柱に移行しました。これにより、C ピラーによって移行プロセス全体が完了します。
樹形図を使用して、4 つのハノイ タワーという大きな問題を 3 つのハノイ タワーと 2 つのハノイ タワーに徐々に分解するプロセスをシミュレートできます。
注: ここでのマージ プロセスの 2、3、および 4 は、各ステップに対応する下部のボックスを表します。
コード:
ハノイの塔の移行プロセスを上記で分析した後、一般的なアイデアを明確に理解したので、ハノイの塔のコードを再帰的に実装します。
まず、再帰関数を設計しましょう。ハノイの塔問題には、ハノイの塔のスライスと 3 本の柱 (A、B、C) だけが含まれるため、これら 2 つを関数として使用します。パラメーター:
void Hanoi(int n, char A , char B , char C);
再帰的終了:
再帰したいので、最初に考慮すべきことは再帰的な終了です。つまり、移行するタワーのスライスの数が 1 の場合、この部分を移行するピラーからターゲットのピラーに直接移行します。これは次のようなコードで表現できます。
if(n == 1){
printf("%c -> %c\n",A,C);
}
再帰的なプロセス:
移行するハノイ塔のスライスが n 枚あると仮定します。上で分析した分解と結合プロセスによると、最初に行う必要があるのは、下部フレームを除くすべての上部フレームを B ピラーに移行することです。つまり、転送 n - 1 ボックスはピラー C をバイパスしてピラー B に移行します。これをコードで表します。
Hanoi(n - 1,'A','C','B');
n - 1 個のボックスをピラー B に正常に移行したら、次に考慮する必要があるのは、n 番の基になるボックスをターゲットのピラー (ピラー C)、つまり A -> C にコードを使用して移行することです。つまり、次のことを意味します。
printf("%c -> %c\n",'A','C');
次に考慮すべきことは、ピラー B のボックスをピラー C に順番に移行することです。つまり、n - 1 個のピースをピラー A をバイパスしてピラー C に移行することをコードで表します。
Hanoi(n - 1,'B','A','C');
これまでに、n 個の正方形を持つハノイの塔が移行されました。
完全なプログラム コード:
#include<stdio.h>
void Hanoi(int n,char A,char B,char C)
{
if(n == 1){
printf("%c -> %c\n",A,C);
}
else{
Hanoi(n - 1 , A,C,B);
printf("%c -> %c\n",A,C);
Hanoi(n - 1,B,A,C);
}
}
int main()
{
int n = 0;
printf("Please enter the number of slice :");
scanf("%d",&n);
Hanoi(n,'A','B','C');
return 0;
}
操作結果:
たとえば、ここではハノイの塔の箱の数を 3 と入力します。
実行結果の移行プロセスは、上で分析した 3 つのハノイの塔の移行プロセスとまったく同じであり、結果は正しいです。
参考文献:
百度百科事典- ハノイ塔