回答編集履歴
1
別のプログラムを追記
answer
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
以前作ったプログラムですが、同じように柱にある円盤を配列で管理しています。
|
2
2
|
`0`が円盤なしで、`1`が一番小さな円盤です。
|
3
|
-
プログラムとしては特段説明するほどのものでも無く、良くあるハノイの塔を再帰で解くアルゴリズムです。
|
3
|
+
プログラムとしては特段説明するほどのものでも無く、良くあるハノイの塔を再帰で解くアルゴリズムです。円盤を移動するごとに配列を更新して、表示しています。
|
4
|
-
円盤を移動するごとに配列を更新して、表示しています。
|
5
4
|
表示はお好みに合わせてどうぞ。
|
6
5
|
|
7
6
|
工夫というほどのものでは無いですが、円盤の管理がし易いように、一番上に載っている円盤の位置を記憶する配列を用意しています。`-1`が円盤なし、`0`が円盤一枚です。
|
@@ -75,4 +74,58 @@
|
|
75
74
|
|
76
75
|
hanoi(n, 1, 3); //ハノイの塔を解く
|
77
76
|
}
|
77
|
+
```
|
78
|
+
---
|
79
|
+
配列を一つで、円盤がどの柱にあるか管理する方法もあります。
|
80
|
+
この方がプログラムはシンプルになりますが、表示がちょっと面倒です。
|
81
|
+
```C
|
82
|
+
#include <stdio.h>
|
83
|
+
|
84
|
+
#define N 6 //円盤の枚数(デフォルト)
|
85
|
+
#define MAX 32
|
86
|
+
|
87
|
+
char disk[MAX]; //円盤を記録
|
88
|
+
|
89
|
+
//塔の状態を表示
|
90
|
+
void Disp(int n)
|
91
|
+
{
|
92
|
+
if (n > 0) printf("%d回目\n", n);
|
93
|
+
for (int p = 'A'; p < 'C' + 1; ++p) { //柱の'A'から'C'まで
|
94
|
+
printf("%c:", p); //柱を表示
|
95
|
+
for (int j = N; j >= 0; --j) { //大きな円盤から表示
|
96
|
+
if (disk[j] == p) { //円盤がその柱にあれば
|
97
|
+
printf("%2d", j + 1); //円盤を表示
|
98
|
+
}
|
99
|
+
}
|
100
|
+
printf("\n");
|
101
|
+
}
|
102
|
+
printf("//-----\n");
|
103
|
+
}
|
104
|
+
|
105
|
+
//ハノイの塔を解く
|
106
|
+
void Hanoi(int n, char X,char Y,char Z)
|
107
|
+
{
|
108
|
+
static int k = 0;
|
109
|
+
if (n > 0) {
|
110
|
+
Hanoi(n - 1, X, Z, Y);
|
111
|
+
disk[n - 1] = Z; //移動先を記録
|
112
|
+
Disp(++k);
|
113
|
+
Hanoi(n - 1, Y, X, Z);
|
114
|
+
}
|
115
|
+
}
|
116
|
+
|
117
|
+
int main(void)
|
118
|
+
{
|
119
|
+
int n;
|
120
|
+
|
121
|
+
printf("ハノイの塔\n円盤の枚数:");
|
122
|
+
if (scanf("%d", &n) < 1) return 1;
|
123
|
+
if (n < 1 && MAX < n) n = N;
|
124
|
+
|
125
|
+
for (int i = 0; i < n; ++i) {
|
126
|
+
disk[i] = 'A'; //'A'の柱に全ての円盤がある
|
127
|
+
}
|
128
|
+
Disp(0); //初期状態を表示
|
129
|
+
Hanoi(n, 'A', 'B', 'C');
|
130
|
+
}
|
78
131
|
```
|