Puzzle N-Queens


17

(Meskipun 60+ pertanyaan ditandai , kami tidak memiliki tantangan n-ratu sederhana.)

Dalam catur, Puzzle N-Queens digambarkan sebagai berikut: Diberikan n x npapan catur dan nratu, atur ratu ke papan catur sehingga tidak ada dua ratu yang saling mengancam. Di bawah ini adalah contoh solusi untuk n = 8, yang dipinjam dari Wikipedia.

Contoh solusi 8-queens dari Wikipedia

Atau, dalam rendering ASCII:

xxxQxxxx
xxxxxxQx
xxQxxxxx
xxxxxxxQ
xQxxxxxx
xxxxQxxx
Qxxxxxxx
xxxxxQxx

Tantangannya di sini adalah untuk mengambil input ndan output representasi ASCII dari solusi untuk npuzzle -Queens. Karena ada lebih dari satu solusi yang mungkin (mis., Setidaknya, rotasi atau refleksi), kode Anda hanya perlu menampilkan solusi yang valid.

Memasukkan

Integer positif tunggal ndengan n >= 4 format apa pun yang nyaman . (n = 2 dan n = 3 tidak memiliki solusi, dan n = 1 adalah sepele, jadi itu dikecualikan)

Keluaran

Representasi ASCII yang dihasilkan dari solusi untuk puzzle N-queens, seperti diuraikan di atas. Anda dapat memilih dua nilai ASCII yang berbeda untuk mewakili ruang kosong dan ratu. Sekali lagi, ini bisa berupa output dalam format yang sesuai (string tunggal, daftar string, array karakter, dll.).

Aturan

  • Leading atau trailing newlines atau spasi putih semuanya opsional, serta spasi putih di antara karakter, selama karakter itu sendiri berbaris dengan benar.
  • Anda dapat menggunakan algoritme untuk menghitung posisi yang mungkin, atau menggunakan gaya solusi "tangga-langkah" eksplisit, yang mana pun sesuai dengan kode golf Anda.
  • Program lengkap atau fungsi dapat diterima. Jika suatu fungsi, Anda dapat mengembalikan output daripada mencetaknya.
  • Jika memungkinkan, harap sertakan tautan ke lingkungan pengujian online sehingga orang lain dapat mencoba kode Anda!
  • Celah standar dilarang.
  • Ini adalah sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.

Contohnya

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
Bisakah Anda memberikan testcases untuk input aneh?
Kritixi Lithos

@Cowsquack Ditambahkan n = 7 contoh
AdmBorkBork

1
@KeyuGan Sesuatu seperti jawaban MATL? Ya, tidak apa-apa.
AdmBorkBork

2
@JonathanAllan Tidak ada pengecualian yang dimaksudkan, selama program selesai dalam waktu yang terbatas dengan probabilitas satu (sebagai standar untuk semua pengiriman).
AdmBorkBork

Jawaban:


5

MATL , 33 32 27 byte

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

Cobalah online!

Gaya semi-kasar, pendekatan non-determistik:

  1. Hasilkan permutasi acak posisi baris
  2. Hasilkan permutasi acak posisi kolom
  3. Pastikan tidak ada ratu yang berbagi diagonal atau anti-diagonal
  4. Ulangi jika perlu.

Solusi yang diperoleh adalah acak. Jika Anda menjalankan kode lagi, Anda mungkin mendapatkan konfigurasi valid yang berbeda. Waktu berjalan juga acak, tetapi kasus uji terpanjang ( n = 10) selesai dalam waktu sekitar 30 detik di TIO sebagian besar waktu.


Saya tidak yakin ini dianggap sebagai solusi, mengingat itu tidak selalu memberikan jawaban yang benar.
junkmail

1
@ junkmail Hah? Tidak ada hal seperti itu jawaban yang benar, karena ada sebuah beberapa solusi (seperti yang dinyatakan oleh tantangan). Kode selalu memberikan sebuah jawaban yang benar, hanya saja tidak sama setiap kali
Luis Mendo

Secara teori itu mungkin bagi program untuk berjalan sewenang-wenang berkali-kali dan masih gagal memberikan jawaban.
junkmail

1
@ junkmail Tapi itu selesai dalam waktu yang terbatas dengan probabilitas satu
Luis Mendo

1
@ James Hollis saya tidak setuju. Itu bisa membuat beberapa permutasi lebih mungkin daripada yang lain, tetapi itu tidak akan mencegah permutasi muncul. Jadi solusinya akhirnya akan tercapai. Dan di samping itu, dengan asumsi generator acak ideal biasanya diterima
Luis Mendo

5

C, 114 byte

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);}

Mencetak solusi secara langsung dalam waktu O (1).


1
Tidak jelas bagi saya bagaimana bisa O (1) dengan loop berulang sebanyak n kali. Bagaimana semua perhitungan itu selalu dapat dilakukan dalam waktu yang konstan?
poi830

1
@ poi830 Maksudku O (1) waktu perhitungan per baris untuk menentukan posisi ratu.
orlp

tidak bisakah Anda menyimpan sedikit dengan membuat variabel baru untuk n/2?
Jeffmagma

Sarankan n-=o=n%2;for(y=n+o;y--;)bukannyao=n%2;n-=o;for(y=0;y<n+o;++y)
ceilingcat

2

Mathematica, 103 108 110 117 byte

-5 byte untuk DuplicateFreeQ->E!=##&@@@

-7 byte untuk ReplacePart[Array[],] ->SparseArray[]

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

Kembalikan array 2D. Dibutuhkan 2,76 untuk menghitung f[6]dan 135 untuk f[7]. (Dalam versi saat ini, -menjadi 0dan Qke 1.

keluaran

Algoritma ini mirip dengan jawaban MATL tetapi di sini kodenya benar-benar kasar.


1

C - 222 byte

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]);}

Kode ini bukan milik saya, tetapi dari IOCCC . Saya harap saya tidak melanggar aturan apa pun. Juga, ini menampilkan semua solusi untuk N antara 4 dan 99. Saya akan mencoba untuk mendapatkan tautan TIO nanti.


Karena kode ini bukan milik Anda, bisakah Anda mengubahnya menjadi Wiki Komunitas? (cukup klik tombol di bawah jendela pengeditan yang bertuliskan "Komunitas Wiki")
caird coinheringaahing

Hai QuaerendoInvenietis dan selamat datang di PPCG. Seperti yang saat ini ditulis, ini sepertinya tidak mengambil angka tertentu sebagai input dan output hanya solusi itu.
AdmBorkBork

1

Jelly , 24 21 byte

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

Cobalah online!

Dengan asumsi setiap ratu ditempatkan pada baris terpisah, kita hanya perlu menemukan indeks kolom untuk menempatkan masing-masing ratu untuk menghindari konflik, yang dapat ditemukan dengan menghasilkan permutasi acak dari [1, 2, ..., n] dan mengujinya.

Penjelasan

,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

Tidak bisakah Anda menggunakan Œc€sebagai ganti œc€2-1?
Erik the Outgolfer

1

Python 3, 204 189 byte

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

Brute force search melalui semua permutasi. Saya dapat menghapus * dan mencetak daftar pemahaman, tetapi mereka terlihat mengerikan.

Keluaran:

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

Sedikit tidak berbulu:

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 byte

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

Cobalah online!

Ini lebih atau kurang didasarkan pada solusi C oleh orlp .

Penjelasan

Kode sumber dengan jalur eksekusi disorot

*Baca jumlah ratu, q , dari stdin dan hitung dua variabel untuk digunakan nanti:, n = q - q%2dan hn = n/2
*Mulai loop utama, iterasi r , nomor baris, dari q ke 0, penurunan pada awal loop, jadi r pertama is q minus 1.
*Hitung offset ratu di setiap baris dengan rumus berikut:

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

*Output mengimbangi karakter spasi untuk indentasi posisi ratu untuk baris saat ini, ditambah satu ruang tambahan hanya karena itu membuat loop output lebih mudah.
*Keluarkan Quntuk ratu, diikuti oleh baris baru untuk pindah ke baris berikutnya.
*Tes jika r adalah nol, dalam hal ini kita telah mencapai ujung papan dan dapat keluar, jika tidak kita ulangi loop utama lagi.


0

Haskell , 145 byte

Pendekatan brute force yang jelas:

b=1>0
t[]=b
t(q:r)=all(/=q)r&&foldr(\(a,b)->(abs(q-b)/=a&&))b(zip[1..]r)&&t r
q n|y<-[1..n]=(\q->(' '<$[1..q])++"Q")<$>[x|x<-mapM(\_->y)y,t x]!!0

Cobalah online!


0

Retina , 136 byte

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

Cobalah online! Port jawaban C orlp sangat bagus. Penjelasan:

.+
$* 

Konversikan ke unary, menggunakan spasi (ada spasi setelah *).

$_;$`Q¶

Buat Nbaris dengan Nspasi, a ;, lalu 0..N-1spasi, lalu a Q. Tahap yang tersisa berlaku untuk semua baris.

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

Membagi integer Ndengan 2. (Juga membungkus hasilnya :;agar lebih mudah untuk jangkar pola.)

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

Jika indeks loop sama dengan N/2*2, maka biarkan saja banyak ruang.

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

Jika N/2kelipatan 3, maka gandakan indeks loop plus satu, modulo N/2*2+1.

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

Kalau tidak, ambil dua kali indeks loop plus (N/2-1)plus 3 tambahan di bagian bawah papan, modulo N/2*2.

( +)%\1?

Sebenarnya melakukan operasi modulo.


0

Arang , 44 byte

Nθ≔÷θ²ηEθ◧Q⊕⎇⁼ι⊗ηι⎇﹪η³﹪⁺⁺⊗ι⊖η׳¬‹ιη⊗η﹪⊕⊗ι⊕⊗η

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Port lain dari jawaban C sangat bagus @ orlp.


0

APL (Dyalog Unicode) , 18 byte SBCS

Program lengkap yang diminta ndari stdin. Mencetak solusi yang dipisahkan ruang untuk stdout menggunakan ·untuk kotak kosong dan untuk Queens.

CY'dfns'
queens

Cobalah online!

⎕CY'dfns'C op y yang "dfns" perpustakaan

 dapatkan input dari stdin

queens temukan semua solusi Queens yang benar-benar unik (tanpa refleksi atau rotasi)

 pilih solusi pertama


0

J , 49 byte

i.=/0({(1-.@e.,)@(([:(=#\){.|@-}.)\."1)#])!A.&i.]

Cobalah online!

Brute force dengan menguji semua permutasi panjang n .

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.