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

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

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

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

1回答

3597閲覧

ハノイの塔を非再帰、スタックを利用して実現する方法(python)

退会済みユーザー

退会済みユーザー

総合スコア0

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

2クリップ

投稿2020/07/25 09:31

ハノイの塔を非再帰でスタックを利用して実現したいです。一例としてC言語では以下のとおりらしいのですが、
これをほぼ同じ考え方でpythonでやろうとすればどうしたらいいでしょうか
どうしても分からず悩んでいます。大変お手数ですが教えていただきたくお願い致します。

C言語

1#include <stdio.h> 2 3/*--- 円盤をx軸からy軸へ移動 ---*/ 4void hanoi(int no, int x, int y) 5{ 6 int xstk[100], ystk[100], sstk[100]; /* スタック */ 7 int ptr = 0; /* スタックポインタ */ 8 int sw = 0; 9 10 while (1) { 11 if (sw == 0 && no > 1) { 12 xstk[ptr] = x; /* xの値をプッシュ */ 13 ystk[ptr] = y; /* yの値をプッシュ */ 14 sstk[ptr] = sw; /* swの値をプッシュ */ 15 ptr++; 16 no = no - 1; 17 y = 6 - x - y; 18 continue; 19 } 20 printf("[%d]を%d軸から%d軸へ移動\n", no, x, y); 21 if (sw == 1 && no > 1) { 22 xstk[ptr] = x; /* xの値をプッシュ */ 23 ystk[ptr] = y; /* yの値をプッシュ */ 24 sstk[ptr] = sw; /* swの値をプッシュ */ 25 ptr++; 26 no = no - 1; 27 x = 6 - x - y; 28 if (++sw == 2) sw = 0; 29 continue; 30 } 31 do { 32 if (ptr-- == 0) /* スタックが空になったら */ 33 return; 34 x = xstk[ptr]; /* 値を保存していたxをポップ */ 35 y = ystk[ptr]; /* 値を保存していたyをポップ */ 36 sw = sstk[ptr] + 1; /* 値を保存していたswをポップ */ 37 no++; 38 } while (sw == 2); 39 } 40} 41 42int main(void) 43{ 44 int n; /* 円盤の枚数 */ 45 46 printf("円盤の枚数:"); 47 scanf("%d", &n); 48 49 hanoi(n, 1, 3); 50 51 return (0) 52コード

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

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

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

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

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

Zuishin

2020/07/25 09:35

目的はこのコードを理解することですか? それとも Python のコードさえ手に入ればいいんですか?
退会済みユーザー

退会済みユーザー

2020/07/25 10:24

ご連絡ありがとうございます。 Pythonのコードをいただきたいです。内容理解は自分で頑張ってみます。
Zuishin

2020/07/25 10:33

https://teratail.com/help/avoid-asking > 何かを作りたいのでコードを書いてほしい、学校の課題を解いてほしい等の質問は、具体的にプログラミングで困っている質問ではないと考え、推奨していません。 > 問題や質問は実際に調査や作業に取り組み、具体的なところで生まれると考えるためです。 > まずは実際に作業に取り組み、つまづいたところで投稿をしてみてください。 つまり、適当に探した意味もわからない C のコードを載せて「あとよろしく」というのではなく、自分でプログラミングするにあたってつまずいた「部分」について質問してください。「どこから手を付けていいかまるでわからない」のであれば、もっと基礎に戻ってやり直してください。 この課題の場合、まず Python で再帰を使ったコードを書き、それをスタックを使って書き直すという手順がやりやすいと思います。
Zuishin

2020/07/25 10:40 編集

なお、推奨していない質問には低評価が付き、回答がつきにくくなるシステム的なペナルティも課されます。 https://teratail.com/help#about-questionevaluation > 低評価がつく質問 > > プログラミングに関係のない質問 > やってほしいことだけを記載した丸投げの質問 > 問題・課題が含まれていない質問 > 意図的に内容が抹消された質問 > 過去に投稿した質問と同じ内容の質問 > 広告と受け取られるような投稿 https://teratail.com/help/avoid-asking > 推奨していない質問 > > プログラミングに関係のない質問 > コードをください・デバッグしてください等の丸投げの質問 > 問題・課題が含まれていない質問 > 意図的に内容が抹消された質問 > 過去に投稿した質問と同じ内容の質問 > 広告と受け取られるような質問
guest

回答1

0

あらら、脱会しちゃたんですか!
C→Python変換したのでもったいないので載せておきます。
ロジックは見てません。単純にC→Python変換しただけです。
pythonではdo~whileがなくwhileしかないのでそこが肝。
一応Cでの結果と変換したPythonの結果は同じなのは確認してます。

python

1# /*--- 円盤をx軸からy軸へ移動 ---*/ 2def hanoi(no, x, y): 3 #xstk[100], ystk[100], sstk[100]; # /* スタック */ 4 xstk = [0] * 100 5 ystk = [0] * 100 6 sstk = [0] * 100 7 ptr = 0 # /* スタックポインタ */ 8 sw = 0 9 10 while True: 11 if sw == 0 and no > 1: 12 xstk[ptr] = x # /* xの値をプッシュ */ 13 ystk[ptr] = y # /* yの値をプッシュ */ 14 sstk[ptr] = sw # /* swの値をプッシュ */ 15 ptr += 1 16 no -= 1 17 y = 6 - x - y 18 continue 19 print("[{}]を{}軸から{}軸へ移動".format(no, x, y)) 20 if sw == 1 and no > 1: 21 xstk[ptr] = x # /* xの値をプッシュ */ 22 ystk[ptr] = y # /* yの値をプッシュ */ 23 sstk[ptr] = sw # /* swの値をプッシュ */ 24 ptr += 1 25 no -= 1 26 x = 6 - x - y 27 sw += 1 28 if sw == 2: 29 sw = 0 30 continue 31 if ptr == 0: 32 ptr -= 1 33 return 34 ptr -= 1 35 x = xstk[ptr] # /* 値を保存していたxをポップ */ 36 y = ystk[ptr] # /* 値を保存していたyをポップ */ 37 sw = sstk[ptr] + 1 # /* 値を保存していたswをポップ */ 38 no += 1 39 while sw == 2: 40 if ptr == 0: # /* スタックが空になったら */ 41 ptr -= 1 42 return 43 ptr -= 1 44 x = xstk[ptr] # /* 値を保存していたxをポップ */ 45 y = ystk[ptr] # /* 値を保存していたyをポップ */ 46 sw = sstk[ptr] + 1 # /* 値を保存していたswをポップ */ 47 no += 1 48 49def main(): 50 n = int(input("円盤の枚数:")) 51 hanoi(n, 1, 3) 52 return 0 53 54if __name__ == '__main__': 55 main() 56

投稿2020/07/25 12:49

ikapy

総合スコア1167

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問