質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

4回答

2233閲覧

ハノイの塔 途中経過の記載

YuhiKUROIWA

総合スコア9

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/06/14 10:12

編集2020/06/14 11:46

ハノイの塔の問題についてです。1~10までの数字でそれぞれ出力されるプログラムを作ります。
5のときの例です。
01234 ..... .....
.1234 ..... ....0
..234 ....1 ....0
..234 ...01 .....
...34 ...01 ....2
..034 ....1 ....2
..034 ..... ...12
...34 ..... ..012
一部ですが,表示が上記のようになるようにしたいです。
2の時ですが
01 .. ..
.1 0. ..
.. 0. .1
.. .. 01
と表示されてしまいます。
01 .. ..
.1 .0 ..
.. .0 .1
.. .. 01
これが正しい結果です。
途中過程の出力が上手くいきません。何か回答いただけると嬉しいです。コードは貼っています。よろしくお願いします。

コード#include <stdio.h> char col[3][10]; void Hanoi(int n, int a, int b, int c){ if(n>1){ Hanoi(n-1, a, c, b); } int f; f=col[a][n-1]; int d; for(d=0;d<n;d++){ col[a][d]='.'; } int e; for(e=0;e<n;e++){ col[c][e]='.'; } col[c][n-1]=f; printf("%s %s %s\n", col[0], col[1], col[2]); if(n>1){ Hanoi(n-1, b, a, c); } } int main(void){ int n; scanf("%d", &n); int i; for(i=0;i<n;i++){ col[0][i]='0'+i; col[1][i]='.'; col[2][i]='.'; } printf("%s %s %s\n", col[0], col[1], col[2]); Hanoi(n, 0, 1, 2); return 0; }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Bull

2020/06/14 11:10

このプログラムでは円盤の移動ができないような気がします。 移動するのは一番上の円盤です。そのためには、一番上の円盤の位置を別途記録しておくか、その都度検索する必要があります。 移動するときに、検索しているようにはみえないのですが。
YuhiKUROIWA

2020/06/14 11:47

ご指摘ありがとうございます。 コードを上記のように変更した結果、一番上の円盤が動くようになったのですが出力が上手くいきませんでした。どうすればよいか意見いただけると嬉しいです。
Bull

2020/06/14 12:35

多分このままのやり方ではダメです。 えっと、どうしましょうか? そのものズバリの回答が欲しければ、つい最近同じような質問がありました。 私も回答していますが、私の方法はちょっと違うので、余り参考にならないと思います。 別の回答者の方 (shiracamus さん) の回答が参考になるのでは無いかと思います。 もし、自分で考えたいというのであれば、ヒントだけにします。 現状では、円盤の位置が変わってないです(中に浮いている)。 '.' は円盤がない状態ですので、それを検索していけば、一番上の円盤が見付かります。また、移動する先も '.' を検索していくことで、移動すべき位置がわかります。
YuhiKUROIWA

2020/06/14 13:53

自分で考えてみたいのですが、全く何をすればいいかわかりません。もう少しヒントをいただけると嬉しいです。
kazuma-s

2020/06/14 17:26

> 1~10までの数字でそれぞれ出力されるプログラムを作ります。 0~9 ではないのですか?
guest

回答4

0

ヒントだけと言うことなので、コードは最小限にします。
col[a][]からcol[c][]に円盤を移動するというのは間違っていないです。すでにコメントしていますが、col[][]には円盤が上から記録されていますが、円盤が無いところは '.' です。
col[a][]の一番上の円盤を探して、col[c][]の一番上に移動します。

最初に移動すべき円盤を探します。

C

1for (d = 0; d < 10; d++) { 2 if (col[a][d] != '.') { 3 //一番上の円盤が見付かった 4 break; 5 } 6}

次の移動先の位置を決めます。

C

1for (e = 0; d < 10; e++) { 2 if (col[c][e + 1] != '.') { //e+1 で一番上の円盤を見つける 3 //col[c][e] に移動する 4 break; 5 } 6}

こんな感じでできるかと思います。

投稿2020/06/15 03:01

Bull

総合スコア986

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YuhiKUROIWA

2020/06/15 03:36

詳しいヒントありがとうございます。 あとは自分で考えられそうなのでやってみます。
guest

0

ベストアンサー

文字列の最後には '\0' が必要なので
char col[3][10]; では円盤を 9枚までしか置けません。
円盤の最上段の位置を憶えておくと、関数 Hanoi の中でループは不要になります。

C

1#include <stdio.h> 2 3char col[3][11], top[3]; 4 5void Hanoi(int n, int a, int b, int c) 6{ 7 if (n > 1) Hanoi(n-1, a, c, b); 8 col[c][--top[c]] = col[a][top[a]]; 9 col[a][top[a]++] = '.'; 10 printf("%s %s %s\n", col[0], col[1], col[2]); 11 if (n > 1) Hanoi(n-1, b, a, c); 12} 13 14int main(void) 15{ 16 int n; 17 if (scanf("%d", &n) != 1 || n < 1 || n > 10) return 1; 18 for (int i = 0; i < n; i++) 19 col[0][i] = '0' + i, col[1][i] = col[2][i] = '.'; 20 top[1] = top[2] = n; 21 printf("%s %s %s\n", col[0], col[1], col[2]); 22 Hanoi(n, 0, 1, 2); 23 return 0; 24}

投稿2020/06/15 01:55

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YuhiKUROIWA

2020/06/15 03:37

なるほど、コードまで本当にありがとうございます。理解したうえでまた自分でも考えてみたいと思います。
guest

0

単純に 1の場合を考えるとどうなるでしょうか。

col[c][e]=col[a][d]; その前の for() で、 d, e は、 n になってますが、よいですか? 多分、どちらも n-1
でも、col[a][n-1]は、直前の for()で更新されてるので、そのまま、使えません。 for() の前に、一旦、保存すべきでしょう。
また、col[c][e+1]='.';e+1は最後に nとなるので、適切でないですね。

なんて考えると以下のようになりました。(変数の宣言、その他省略)

C

1 f = col[a][n-1]; 2 for(d=0;d<n;d++) col[a][d]='.'; 3 for(e=0;e<n;e++) col[c][e]='.'; 4 col[c][n-1]=f;

深く考えてなく、申し訳ないですが、、動くみたいです。

投稿2020/06/14 11:26

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YuhiKUROIWA

2020/06/14 11:43

ありがとうございます。 1のとき上手くいきました。
guest

0

c

1 int d; 2 for(d=0;d<n;d++){ 3 col[a][d]='.'; 4 } 5 /* 中略 */ 6 col[c][e]=col[a][d];

このような形なので、下の行でdnになっています。おそらく、意図しないところを指しているのではないかと思います。

投稿2020/06/14 10:16

maisumakun

総合スコア145184

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

YuhiKUROIWA

2020/06/14 11:49

ご意見ありがとうございます。 上記の様にコードを修正しました。出力が上手くいかなかったのですが、どこがどううまくいっていないのか具体的に教えていただけると助かります。よろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問