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

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

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

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

Q&A

解決済

3回答

2220閲覧

ハノイの塔についての質問

Japanise

総合スコア11

C

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

0グッド

0クリップ

投稿2020/08/10 16:56

編集2020/08/11 00:28

ハノイの塔でn枚の円盤の移動手順を比較的短く出力するプログラムを下のプログラムを基にhanoimove関数の中を再帰呼び出しを使い完成させなさいという問題があるのですがどーすればいいのかわかりません。

ハノイの塔とは3つの棒あるいは杭を基に考えるのですが、移動前の塔をA,移動先の塔をB,残りの塔をCとすると,
■ AからCにN-1枚を移動
■ AからBに1枚を移動
■ CからBにN-1枚を移動
とすることができ、A.Bの組み合わせは  A+B+C=6
の関係が成り立ち、 C = 6-(A+B)
とすることができるからint another = 6-(before+after)と表せるのかなと思いました。

void hanoidisk( int before, int after ){
printf("杭%dから杭%dに移動\n", before, after);
}

void hanoimove( int before, int after , int num){
int another = 6-(before+after);

}

int main(void) {
int n=5;
printf("%d枚の円盤を杭1から杭3に移動させる手順は次のとおり:\n", n);
hanoimove( 1, 3, n );
return 0;
}

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

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

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

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

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

cateye

2020/08/10 17:05

“ハノイの塔 c言語 再帰”で検索すればかなりヒットしますが?
Japanise

2020/08/10 17:10 編集

検索したのですが、私はハノイの塔は三つの杭があるため全部で6通りあり6通りをもとにプラグラムを作りたいのですがそれについてのサイトがなかったのです。ですのでお願いしたいです。
Japanise

2020/08/10 17:38 編集

ハノイの塔とは3つの棒あるいは杭を基に考えるのですが、移動前の塔をA,移動先の塔をB,残りの塔をCとすると,  ■ AからCにN-1枚を移動  ■ AからBに1枚を移動  ■ CからBにN-1枚を移動 とすることができ、A.Bの組み合わせは  A+B+C=6 の関係が成り立ち、   C = 6-(A+B) とすることができると思ったのですが… http://www.algolism.iinaa.net/50/53.htm
cateye

2020/08/10 17:51 編集

最短手順→2**N-1の事を言っていますか? ---->8---->8---->8---->8---->8---->8---- usr ~/Project/test % ./a.out 3 1 を A から C へ 2 を A から B へ 1 を C から B へ 3 を A から C へ 1 を B から A へ 2 を B から C へ 1 を A から C へ usr ~/Project/test % ./a.out 2 1 を A から B へ 2 を A から C へ 1 を B から C へ
Japanise

2020/08/10 17:53

そーです! 私の説明が下手すぎて申し訳ないです。
guest

回答3

0

3つの棒に1, 2, 3と名前をつけます。ある円盤を移動させる際、移動前の棒の名前をA, 移動後の棒の名前をB, 残りの棒の名前をCとします。(A, B, Cはすべて異なる) すると、{A, B, C}={1, 2, 3}となるので、必ずA+B+C=6が成立します。({}は順序を考えないという意味)
そうすると、C=6-A-Bが成り立ちます。例えば1から3に円盤を移動させたいとなった時、A=1, B=3なので、C=6-1-3=2となります。つまり、この式に移動前と移動後の棒の名前を与えてやれば、その残りの棒の名前がわかるというだけで、それ以上の意味はありません。
なので、棒の選び方としては3!=6通りと言われればその通りなのですが、特にこれを考えたからといって問題を解けるわけではないと思います。(再帰を使うしかない)

投稿2020/08/11 00:11

編集2020/08/11 00:40
Penpen7

総合スコア698

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

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

rubato6809

2020/08/12 22:28

> 6通りと言われればその通りなのですが、特にこれを考えたからといって問題を解けるわけではない その通りです。現にcateyeさんのコードに「C = 6-(A+B)」に相当するコードはありません。「再帰を使うしかない」のであって、その都度3つの棒をどう使いまわすかを考えれば済むことです。
guest

0

ベストアンサー

「n-1枚を○○して、残る1枚を○○し、先程のn-1枚を○○する」

○○を埋めてみた。

C

1#include<stdio.h> 2 3void hanoidisk( int before, int after ){ 4 printf("杭%dから杭%dに移動\n", before, after); 5} 6 7void hanoimove( int before, int after , int num){ 8 int another = 6-(before+after); // 底板の上に重なった板を退避させる杭の番号 9 10 // before から after へ num 枚を移動するには 11 12 // before から another へ(底板の上に重なる)num-1 枚を移動し、 13 if ( num != 1 ) hanoimove(before, another, num-1); 14 15 // 底板を before から after へ 16 hanoidisk(before, after); 17 18 // another から after へ(退避しておいた)num-1 枚を移動する 19 if ( num != 1 ) hanoimove(another, after, num-1); 20} 21 22int main(void) { 23 int n=5; 24 printf("%d枚の円盤を杭1から杭3に移動させる手順は次のとおり:\n", n); 25 hanoimove( 1, 3, n ); 26 return 0; 27}

投稿2020/08/10 23:41

編集2020/08/11 00:10
episteme

総合スコア16612

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

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

0

ハノイの塔を攻略せよ!の月刊アスキーからの引用。まんまですが・・・

c

1#include <stdio.h> 2#include <stdlib.h> 3// 4static void Hanoi(int n, char *from, char *work, char *dest) 5{ 6 if(n >= 1) { 7 Hanoi(n - 1, from, dest, work); 8 9 printf("%d を %s から %s へ\n", n, from, dest); 10 11 Hanoi(n - 1, work, from, dest); 12 } 13} 14 15int main(int agc, char *agv[]) 16{ 17 if(agc != 2){ 18 return 1; 19 } 20 // 21 int num = (int)strtol(agv[1], 0, 10); 22 Hanoi(num, "A", "B", "C"); 23 24 return 0; 25} 26

18枚で手元(Linux)では1秒かかります。

投稿2020/08/10 18:10

cateye

総合スコア6851

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

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

Japanise

2020/08/10 18:46

なぜ回答に引用したものを貼ったのでしょうか?何の回答にもなっていません。
cateye

2020/08/10 22:37 編集

私は「“ハノイの塔 c言語 再帰”で検索すればかなりヒットしますが? 」と言いました。 あなたは、それに対して『それについてのサイトがなかったのです。』と言ったので、 ヒットしたものを(テストのために一部変更して)「引用」として提示しました。 ・・・で、「再帰呼び出し」↓は、解決しましたか?・・・  “static void Hanoi(int n, char *from, char *work, char *dest)”
Japanise

2020/08/10 23:41

ごめんなさい。私の勘違いでした。申し訳ないです。 6-(before+after);とはどのようにつなげれば良いでしょうか?
dodox86

2020/08/10 23:43

横からすみません。今後の混乱を避けて欲しいがためのコメントなのですがが: 質問者さんは当初、cateyeさんの「“ハノイの塔 c言語 再帰”で検索すればかなりヒットします」のアドバイスに対して、検索はしたものの > 私はハノイの塔は三つの杭があるため全部で6通りあり6通りをもとにプラグラムを作りたい と述べられていました。で、この点、つまり6通りになることについて説明しているサイトが無かった、と言われているのだと思いました。再帰の話はとりあえず置いておいて。 ですが、質問者さんが挙げたサイトで、A+B+C=6通りを示す表がその文中で何を示そうとしているのか正直、私自身も分かりませんでしたね。 (N-1)の円盤のかたまりを1つとして、3つの棒の間をどのように配置できるか、の組み合わせかな? 質問者さんの当初の質問に回答として応えることは私にはできそうにありませんが、ハノイの塔では円盤が何枚あろうと、(N-1)の円盤を1つのかたまりとして考えると、円盤3枚の移動になぞらえることができます。それを踏まえて再帰を考えるともしかしたら少し分かりやすくなるかもしれません。いかがでしょう。で、結局再帰が必要になります。
episteme

2020/08/11 00:04

>(N-1)の円盤を1つのかたまりとして考えると、円盤3枚の移動になぞらえることができます。 円盤2枚の移動。
dodox86

2020/08/11 01:44

epistemeさん、ご指摘どうもありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問