teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

別のプログラムを追記

2020/06/12 13:58

投稿

Bull
Bull

スコア986

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
  ```