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

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

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

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

Q&A

解決済

1回答

830閲覧

8クイーンの解を求め、回転させるプログラミングを求めたいです

退会済みユーザー

退会済みユーザー

総合スコア0

Python

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

1グッド

1クリップ

投稿2020/08/18 14:16

編集2020/08/25 03:10

引用テキストPythonの8クイーン問題についてです。

8クイーンの解を求め、回転させるプログラムを書こうとしています。

92通りの並べ方は出せたのですが、回転させるプログラムと言われると途端にわからなくなってしまいました。

図が提示されている場合、回転したクイーンの位置を数字では表せますがプログラミングはどのようになるのでしょうか。

どなたか教えていただけると幸いです。
初めて質問するので不手際がありましたらすみません。

参考書を見ながら92通りの並べ方は出せました。

yusuke-fusegi👍を押しています

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/08/18 14:41

追記しました。
sfdust

2020/08/18 14:59

そのコードを実行すると 実行結果の1つに、[0, 4, 7, 5, 2, 6, 1, 3]という答えが出ますが、 この出力がどういう意味であるかは分かっていますか?
退会済みユーザー

退会済みユーザー

2020/08/18 15:03

コメントありがとうございます。 8×8の盤に置かれているクイーンの位置の列と行を数字で表しているものだと思っているのですが、この認識で間違いないでしょうか。
meg_

2020/08/18 15:10

コードは「コードの挿入」で記入しましょう。
退会済みユーザー

退会済みユーザー

2020/08/18 15:15

ご指摘ありがとうございます。 どのようにすればよいのかわからずそのまま貼り付けてしまっていました。 今はコードの方に貼り直しました。 ありがとうございます。
meg_

2020/08/18 17:14

> 実行結果の1つに、[0, 4, 7, 5, 2, 6, 1, 3]という答えが出ます と > 8×8の盤に置かれているクイーンの位置の列と行を数字で表しているもの の対応についてよく分かりません。
guest

回答1

0

ベストアンサー

プログラムをそのまま示したのではためにならないと思うので、考え方だけ示します。

1.回転座標

簡単な例で考えましょう。

4x4の場合で考えると、(クイーンの効き筋も無視します)

たとえばcolが[0, 1, 3, 2]の場合
クイーンは

Q . . . . Q . . . . . Q . . Q .

という配置になっています。

それぞれ
横 → 縦の順に座標を考えると

col[0] = 0 → 座標[1, 1]
col[1] = 1 → 座標[2, 2]
col[2] = 3 → 座標[3, 4]
col[3] = 2 → 座標[4, 3]

となっていることがわかります。

上の図を90度左回転させると

. . Q . . . . Q . Q . . Q . . .

という配置になります。

それぞれ回転前と回転後の座標の対応関係を見ると

元の座標[1, 1] → 回転後の座標[1, 4]
元の座標[2, 2] → 回転後の座標[2, 3]
元の座標[3, 4] → 回転後の座標[4, 2]
元の座標[4, 3] → 回転後の座標[3, 1]

となっています。

つまりこれを一般化すると
[a,b] を左に90度回転させた場合、回転後の座標は[b, N-a+1]
という規則性になっていることがわかります。

プログラムにすると、単純に

def rotate(a, b): return [b, N-a+1]

となります。

2.座標と数字の変換

colが[0, 1, 3, 2]の場合
col[0] = 0 → 座標[1, 1]
col[1] = 1 → 座標[2, 2]
col[2] = 3 → 座標[3, 4]
col[3] = 2 → 座標[4, 3]
となっているのですから、これを一般化すると

col[i] = a ならば、 座標[i+1, a+1] にクイーンがあることを示しています。

逆に 座標[x, y]にクイーンがあることを示す場合は、
col[x-1] に y-1を代入すればよいことがわかります。

上記を使ってプログラムを考えてみましょう。

追記

上の説明でN=4の場合、下記のようなコードで変換できます。

N=4 # クイーンの位置を示す配列 test_col = [0,1,3,2] # 回転前のクイーンの座標を格納する配列(初期化) queens_place = [[0]*2 for i in range(N)] # 回転後のクイーンの座標を格納する配列(初期化) rotated_place = [[0]*2 for i in range(N)] # 回転後のクイーンの座標に対応する数値を格納する配列(初期化) rotated_col = [0 for i in range(N)] def rotate(a, b): ''' 与えられた座標を左90度に回転した座標にして返す関数。 ''' return [b, N-a+1] def coordinate_to_value(x, y): ''' 与えられた座標を数字に変換する関数。 返り値の1番目は配列のインデックス、2番目は配列の要素 を表す。 ''' return [x-1, y-1] def value_to_coordinate(index, value): ''' 与えられたインデックスと数値を座標に変換する。 返り値の1番目はx座標、2番目はy座標 を表す。 ''' return [index+1, value + 1] # 元のcol配列を、クイーンのx,y座標に変換してqueens_placeに格納する。 for index in range(N): queens_place[index] = value_to_coordinate(index, test_col[index]) print("現在のクイーンの位置") print(queens_place) print() # クイーンのx,y座標を左90度に回転したものをrotated_placeに格納する。 for index in range(N): x = queens_place[index][0] y = queens_place[index][1] rotated_place[index]=rotate(x, y) print("回転後のクイーンの位置") print(rotated_place) print() # 回転後のクイーンのx,y座標を数字に直して配列にする。 for i in range(N): index, value = coordinate_to_value( rotated_place[i][0], # x座標 rotated_place[i][1] # y座標 ) rotated_col[index] = value print("回転後の座標を数字に変換した後の答え") print(rotated_col)

※詳しい方々へ:説明にそった形にするためかなり冗長で無駄なコードになっています。
タプルを使えとかnumpy使えばすぐできるとかいろいろあると思いますが、ご容赦ください。

投稿2020/08/18 17:16

編集2020/08/19 17:23
sfdust

総合スコア1137

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

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

退会済みユーザー

退会済みユーザー

2020/08/31 13:52 編集

教えていただいたことを参考にし、考えてみたいと思います。 丁寧に説明していただき本当にありがとうございます。
退会済みユーザー

退会済みユーザー

2020/08/19 15:59

昨日は丁寧に教えていただきありがとうございました。 教えていただいたことをもとに一日考えたのですが、どうしてもプログラミングがうまくいきませんでした。 colを座標にして考える事、回転後の座標が[b,N-a+1]になる事は理解することができました。 そこで、教えていただいた def transform(a, b): return [b, N-a+1] のプログラムを実行したのですがエラーになってしまいました。 (a,b)=[(1,4),(2,3),(4,2),(3,1)]にし、実行すると(1, 2, 3, 4, 5, 6, 7, 8) (3, 1, 8, 2, 5, 1, 6, 4)と表示されました。 printを入れてみたり、他の数字に変えて試してみたのですが、繰り返しているうちにわからなくなってしまいました。 もしよろしければもう少し考え方を教えていただけないでしょうか。度重なる質問申し訳ありません。よろしくお願いいたします。
sfdust

2020/08/19 17:02

後半にほぼ回答となるコードを追記しました。
退会済みユーザー

退会済みユーザー

2020/08/20 15:01

教えていただきありがとうございました。 実行してみたところ無事に成功しました。 質問に不慣れで色々とご迷惑をおかけしましたが、丁寧に対応していただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問