Nクイーンズパズル


17

にタグ付けされた60以上の質問にもかかわらず、単純なn-queensチャレンジはありません。)

チェスでは、N-クイーンズパズルは、与えられた次のように記載されているn x nチェス盤とnクイーンないクイーンが互いに脅かすされないように、チェス盤にクイーンを配置します。以下は、n = 8Wikipediaから借用したのソリューション例です。

ウィキペディアの8クイーンのソリューション例

または、ASCIIレンダリングの場合:

xxxQxxxx
xxxxxxQx
xxQxxxxx
xxxxxxxQ
xQxxxxxx
xxxxQxxx
Qxxxxxxx
xxxxxQxx

ここでの課題nは、n-Queensパズルの解のASCII表現を入力および出力することです。複数の可能なソリューション(少なくとも、回転または反射など)があるため、コードは有効なソリューションを出力するだけで済みます。

入力

単一の正の整数nn >= 4 任意の便利な形式で。(n = 2およびn = 3には解がなく、n = 1は自明なので、それらは除外されます)

出力

上記で概説したように、N-queensパズルの解の結果のASCII表現。空白とクイーンを表すために、任意の2つの異なるASCII値を選択できます。繰り返しますが、これは適切な形式(単一の文字列、文字列のリスト、文字配列など)で出力できます。

ルール

  • 文字自体が正しく整列している限り、先頭または末尾の改行または空白はすべてオプションであり、文字間の空白もオプションです。
  • アルゴリズムを使用して可能な位置を計算するか、ソリューションの明示的な「階段状」スタイルのソリューションのいずれかを使用できます。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。関数の場合、出力する代わりに出力を返すことができます。
  • 可能であれば、他の人がコードを試すことができるように、オンラインテスト環境へのリンクを含めてください!
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

n=4
xQxx
xxxQ
Qxxx
xxQx

n=7
xxQxxxx
xxxxxxQ
xQxxxxx
xxxQxxx
xxxxxQx
Qxxxxxx
xxxxQxx

n=10
xxxxQxxxxx
xxxxxxxxxQ
xxxQxxxxxx
xxxxxxxxQx
xxQxxxxxxx
xxxxxxxQxx
xQxxxxxxxx
xxxxxxQxxx
Qxxxxxxxxx
xxxxxQxxxx


1
奇妙な入力のテストケースを教えてもらえますか?
KritixiのLithos

@Cowsquack n = 7の例が追加されました
-AdmBorkBork

1
@KeyuGan MATLの答えのようなものですか?ええ、それでいいです。
-AdmBorkBork

2
@JonathanAllanプログラムが確率1(すべての提出の標準として)で有限時間で終了する限り、そのような除外は意図されていません。
AdmBorkBork

回答:


5

MATL33 32 27バイト

`x,GZ@]1Z?tt!P!,w&TXds]h1>a

オンラインでお試しください!

セミブルートフォース、非決定論的アプローチ:

  1. 行位置のランダムな順列を生成します
  2. 列位置のランダムな順列を生成します
  3. クイーンが対角線または反対角線を共有していないことを確認します
  4. 必要に応じて繰り返します。

得られた解はランダムです。コードを再度実行すると、別の有効な構成を取得できます。実行時間もランダムですが、最長のテストケース(n = 10)はほとんどの場合TIOで約30秒で終了します。


常に正しい答えが得られるとは限らないので、これが解決策としてカウントされるかどうかはわかりません。
ジャンクメール

1
@junkmailえ?いくつかの解決策がありますので正しい答えのようなものはありません(チャレンジで述べられているように)。コードは常に正しい答えを提供ますが、毎回同じではありません
ルイスメンドー

理論的には、プログラムが何度でも任意に実行され、それでも答えが得られない可能性があります。
ジャンクメール

1
@junkmailしかし、それは確率1で有限時間で終了します
ルイスメンドー

1
@JamesHollis私は同意しません。これにより、一部の順列が他の順列よりも可能性が高くなりますが、順列の出現を防ぐことはできません。そのため、最終的に解決策に到達します。さらに、ランダムジェネレーターが理想的であると仮定すると、通常受け入れられます
ルイスメンドー

5

C、114バイト

Q(n,o,y){o=n%2;n-=o;for(y=0;y<n+o;++y)printf("%*c\n",y<n?o+n-(n+y%(n/2)*2+(n%6?y<n/2?n/2-1:2-n/2:y<n/2))%n:0,81);}

O(1)時間でソリューションを直接印刷します。


1
ループがn回繰り返されると、O(1)になる可能性があるかどうかはわかりません。これらの計算のすべてを常に一定の時間で実行するにはどうすればよいですか?
poi830

1
@ poi830クイーンの位置を決定するための行ごとのO(1)計算時間を意味します。
orlp

のために新しい変数を作成して、いくつかを保存できませんでしたn/2か?
ジェフマグマ

提案する n-=o=n%2;for(y=n+o;y--;)代わりにo=n%2;n-=o;for(y=0;y<n+o;++y)
ceilingcat

2

Mathematica、103 108 110 117 バイト

-5バイトDuplicateFreeQ->E!=##&@@@

-7バイトReplacePart[Array[],]->SparseArray[]

SparseArray[Thread@#&@@Select[Permutations@Range@#~Tuples~2,And@@(E!=##&@@@{#-#2,+##})&@@#&]->1,{#,#}]&

2D配列を返します。計算には2.76秒f[6]、には135 秒かかりますf[7]。(現在のバージョンで-0Qします1

出力

アルゴリズムはMATLの回答に似ていますが、ここではコードは完全にブルートフォースです。


1

C-222バイト

v,i,j,k,l,s,a[99];main(){for(scanf("%d",&s);*a-s;v=a[j*=v]-a[i],k=i<s,j+=(v=j<s&&(!k&&!!printf(2+"\n\n%c"-(!l<<!j)," #Q"[l^v?(l^j)&1:2])&&++l||a[i]<s&&v&&v-i+j&&v+i-j))&&!(l%=s),v||(i==j?a[i+=k]=0:++a[i])>=s*k&&++a[--i]);}

コードは私のものではなく、IOCCCからのものです。規則に違反しないことを願っています。また、これは4〜99の間のNのすべてのソリューションを表示します。後でTIOリンクを取得しようとします。


このコードはあなたのものではないので、コミュニティWikiに変換できますか?(編集ウィンドウの下にある「コミュニティWiki」と書かれたボタンをクリックするだけです)
coheringaahing

こんにちはQuaerendoInvenietis、PPCGへようこそ。現在書かれているように、これは特定の数値をその解としてのみ入力および出力としてとるわけではないようです。
-AdmBorkBork

1

ゼリー24 21バイト

,JŒc€IF€An/PC
ẊÇ¿=þRG

オンラインでお試しください!

各クイーンが別々の行に配置されていると仮定すると、競合を避けるために各クイーンを配置する列インデックスを見つけるだけで済みます。これは、 [1, 2, ..., n]テストする。

説明

,JŒc€IF€An/PC  Helper. Input: permutation of [1, 2, ..., n]
 J             Enumerate indices, obtains [1, 2, ..., n]
,              Join
  Œc€          Find all pairs in each
     I         Calculate the difference of each pair
      F€       Flatten each
        A      Absolute value
               (We now have the distance in column between each queen and
                the distance in rows between each queen. If they are unequal,
                the queens do not conflict with each other)
         n/    Reduce using not-equals
           P   Product, returns 1 only if they are all unequal
            C  Complement
               Returns 1 when there is a conflict, else 0

ẊÇ¿=þRG  Main.  Input: n
Ẋ        Shuffle (When given an integer, it will shuffle [1, 2, ..., n])
 Ç¿      While the helper returns 1, continue shuffling
     R   Range, gets [1, 2, ..., n]
   =þ    Equality table (Generates the board as a matrix)
      G  Pretty-print the matrix

-1のŒc€代わりに使用することはできませんœc€2か?
エリックアウトゴルファー

1

Python 3、204 189バイト

import itertools as p
n=int(input())
r=range(n)
b='.'*(n-1)+'Q'
for c in p.permutations(r):
 if len(set((x*z+c[x],z)for x in r for z in[1,-1]))==n+n:[print(*(b[x:]+b[:x]))for x in c];break

すべての順列のブルートフォース検索。*を削除してリストの内包表記を印刷することもできますが、ひどく見えます。

出力:

10
Q . . . . . . . . .
. . Q . . . . . . .
. . . . . Q . . . .
. . . . . . . Q . .
. . . . . . . . . Q
. . . . Q . . . . .
. . . . . . . . Q .
. Q . . . . . . . .
. . . Q . . . . . .
. . . . . . Q . . .

わずかに未使用:

import itertools as p
n=int(input())
r=range(n)
b='.'*(n-1)+'Q'
for c in p.permutations(r):
    if len(set( (x*z+c[x],z) for x in r for z in[1,-1] )) == n+n:
        [print(*(b[x:] + b[:x])) for x in c]
        break

1

Befunge、122バイト

&::2%-v>2*00g++00g%00g\-\00g\`*4>8#4*#<,#-:#1_$55+"Q",,:#v_@
/2p00:<^%g01\+*+1*!!%6g00-2g01\**!!%6g00-g012!:`\g01:::-1<p01

オンラインでお試しください!

これは、多かれ少なかれに基づいているC・ソリューションによってorlp

説明

実行パスが強調表示されたソースコード

*クイーンの数、読み取るQを後で使用するために2つの変数をstdinと計算から、: n = q - q%2、およびhn = n/2
*スタートメインループ、反復Rから、行数、qは 0まで、ループの開始時にデクリメント、第1 のRあるQから1を引いた
*計算は、以下の式を有する各行の女王のオフセット:

offset = (n - (
  (hn <= r) * (2 - hn) * !!(n % 6) + 
  (hn > r) * ((hn - 2) * !!(n % 6) + 1) + 
  (y % hn * 2) + n
) % n) * (n > r)

*出力オフセットそれが簡単に出力ループを作るという理由だけで、空白文字は女王の現在の行の位置、プラスワンの追加スペースをインデントします。クイーンのを
*出力Qし、次の行に移動するための改行が続きます。rがゼロ
*かどうかをテストします。この場合、ボードの最後に到達して終了できます。そうでない場合は、メインループを再度繰り返します。



0

網膜、136バイト

.+
$* 
 
$_;$`Q¶
( +)\1( ?);
:$1;
:( +);\1\1
$1$1
:((   )+);( *)
 $1$1% $3$3
: ( +);( \1)?( *)
 $1 $1%$#2$* $#2$* $#2$* $1$3$3
( +)%\1?

オンラインでお試しください!@orlpの優れたC回答のポート。説明:

.+
$* 

スペースを使用して単項に変換します(の後にスペースがあります*)。

$_;$`Q¶

作成Nと行Nスペース、;、そして0..N-1その後、スペース、Q。残りのステージはすべての行に適用されます。

( +)\1( ?);
:$1;

N2で整数除算します(:;パターンを固定しやすくするために、結果をラップします)。

:( +);\1\1
$1$1

ループインデックスがに等しい場合、N/2*2その数のスペースをそのままにします。

:((   )+);( *)
 $1$1% $3$3

N/2が3の倍数の場合、ループインデックスの2倍に1を加えたモジュロを取りN/2*2+1ます。

: ( +);( \1)?( *)
 $1 $1%$#2$* $#2$* $#2$* $1$3$3

それ以外の場合は、ループインデックスの2倍に(N/2-1)加えて、ボードの下半分に3を加えたモジュロを取りN/2*2ます。

( +)%\1?

実際にモジュロ演算を実行します。



0

APL(Dyalog Unicode)、18バイトSBCS

nstdinからの完全なプログラムプロンプト。·空の正方形とクイーンズを使用して、スペースで区切られたソリューションを標準出力に出力します。

CY'dfns'
queens

オンラインでお試しください!

⎕CY'dfns'C op Y "DFNS"ライブラリ

 stdinから入力を取得する

queens 真にユニークなクイーンズのソリューションをすべて見つける(反射や回転なし)

 最初の解決策を選ぶ


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.