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

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

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

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

5151閲覧

ハノイの塔の実装方法

退会済みユーザー

退会済みユーザー

総合スコア0

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/07/07 01:16

ハノイの塔の実装方法がわからず困っています。
https://p--q.blogspot.jp/2014/06/python13.html
のリンクの通りコードを書くと

# -*- coding: utf-8 -*- def hanoi(n, x, y, z): if n == 1: print("{}→{}".format(x, y)) else: hanoi(n-1, x, z, y) print("{}→{}".format(x, y)) hanoi(n-1, z, y, x) print(hanoi(3, "A", "C", "B"))

で、このファイルを実装すると

A→C A→B C→B A→C B→A B→C A→C

のように7回出力されます。
理解できないのが、なぜfor文やwhile文を使っていないのに
この場合、

else: hanoi(n-1, x, z, y) print("{}→{}".format(x, y)) hanoi(n-1, z, y, x)

が何回も呼ばれるのかということです。
http://www13.plala.or.jp/kymats/study/C++/Hanoi/Hanoi.html
のURLを見ると
#####
n-1 枚の円盤を棒Aから棒Bへ移動する場合と
棒Bから棒Aへ移動する場合は交互に訪れる。
#####
という部分を実装しているとは思うのですが、
このリンクのサイトの図の
■3枚の円盤を移動する手順
のどの部分が#####で囲った説明を表現しているのかもわかりません。
なぜ hanoiメソッドで表現されるシンプルなコードでハノイの塔が実装できるのでしょうか?

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

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

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

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

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

guest

回答3

0

ベストアンサー

hanoi(3, "A", "C", "B") // 3 != 1: goto else hanoi(2, "A", "B", "C") | // 2 != 1: goto else | hanoi(1, "A", "C", "B") | | // 1 == 1: goto if | | print("A -> C") // A -> C | print("A -> B") // A -> B | hanoi(1, "C", "B", "A") | | // 1 == 1: goto if | | print("C -> B") // C -> B print("A -> C") // A -> C hanoi(2, "B", "C", "A") | // 2 != 1: goto else | hanoi(1, "B", "A", "C") | | // 1 == 1: goto if | | print("B -> A") // B -> A | print("B -> C") // B -> C | hanoi(1, "A", "C", "B") | | // 1 == 1: goto if | | print("A -> C") // A -> C

なぜ hanoiメソッドで表現されるシンプルなコードでハノイの塔が実装できるのでしょうか?

解法自体が単純なルールで表現できるからです.

  1. スタートにあるn枚のうち,上からn-1枚を「なんとかして」一時領域に移す(n == 1の時は何もしない)
  2. スタートに残ったものをゴールに移す
  3. すでにゴールにある円盤は無視していい(この先ゴールにある円盤より大きい円盤を動かすことはない)ので,残った n-1 枚を移動する問題と考えて手続き 1 に戻る

コードと照らし合わせると,2つのprint文が手続き 2,else句の一度目の再帰が「なんとかして」部分,二度目の再帰が手続き 3 に相当するはずです.

投稿2017/07/07 02:20

編集2017/07/07 05:54
tamy

総合スコア442

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

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

退会済みユーザー

退会済みユーザー

2017/07/07 04:35

ありがとうございます。ハノイの塔の仕組みが理解できました! 何点か質問がありまして、 3.一時領域をスタート,スタートを一時領域として(役割を交換して),1に戻る に関してですが、スタート,スタートを一時領域 とはどういう意味でしょうか? また、1.スタートにあるn枚のうち,上からn-1枚を一時領域に移す ですが 1のプロセスでn-1枚の全部を一時領域に移すのも何プロセスかありますよね?そのため、else: の中で、hanoi(n-1, x, z, y)・hanoi(n-1, z, y, x)と呼び出しているということなのでしょうか?
tamy

2017/07/07 05:41

> スタート,スタートを一時領域 とはどういう意味でしょうか? 基本的なハノイの塔って,場所(棒)が3つありますよね? スタート:最初に n 枚が置いてある場所(質問文中では棒A) ゴール:最終的に移動したい場所(質問文中では棒C) 一時領域:スタートでもゴールでもない場所(質問文中では棒B) 目的はスタートからゴールに全ての円盤を移すことですが,「小さい円盤の上には大きい円盤を置けない」という制約から,どうしても一時的に円盤を待避しておく場所(一時領域)が必要になります. > 1のプロセスでn-1枚の全部を一時領域に移すのも何プロセスかありますよね?そのため、else: の中で、hanoi(n-1, x, z, y)・hanoi(n-1, z, y, x)と呼び出しているということなのでしょうか? そうです. ここの部分,少し記述を修正します.
guest

0

投稿2017/07/07 01:20

can110

総合スコア38260

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

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

0

再起呼び出しをしているからです。
実行をトレースしてみてください。

投稿2017/07/07 01:19

jm1156

総合スコア866

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

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

退会済みユーザー

退会済みユーザー

2017/07/07 01:24

再起呼び出しをしているのはわかります。 ただ、else: 文の中の hanoi(n-1, x, z, y) と hanoi(n-1, z, y, x) の引数が変わっているのが理解できなくて。最初のhanoiメソッドでは x, z, y と引数を渡しているのに、2番目のhanoiメソッドでは z, y, x と引数を渡していてなぜその順番が変わっているのでしょうか?
jm1156

2017/07/07 01:30

ハノイの塔のアルゴリズムがわかっているならわかるはず。わからないなら調べましょう。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問