N-Queens Yapboz


17

(60+ etiketli soruya rağmen , basit bir n-queens zorluğumuz yok.)

Satrançta, N-Queens Puzzle şu şekilde tanımlanır: Bir n x nsatranç tahtası ve nkraliçeler verildiğinde , kraliçeleri satranç tahtasına yerleştirerek iki kraliçenin birbirini tehdit etmeyeceği şekilde düzenleyin. Aşağıda n = 8Wikipedia'dan ödünç alınmış bir örnek çözüm bulunmaktadır .

Wikipedia'dan 8 kraliçe örnek çözümü

Veya ASCII sunumunda:

xxxQxxxx
xxxxxxQx
xxQxxxxx
xxxxxxxQ
xQxxxxxx
xxxxQxxx
Qxxxxxxx
xxxxxQxx

Buradaki zorluk n, n-Queens bulmacasına bir çözümün ASCII temsilini almak ve çıktı almak olacaktır . Birden fazla olası çözüm (örneğin, en azından bir döndürme veya yansıma) olduğundan, kodunuzun yalnızca geçerli bir çözüm üretmesi gerekir.

Giriş

Tek bir pozitif tam sayı nile n >= 4 uygun olan herhangi bir biçimde . (n = 2 ve n = 3'ün çözümü yoktur ve n = 1 önemsizdir, bu yüzden bunlar hariç tutulur)

Çıktı

Yukarıda belirtildiği gibi N-queens bulmacasına bir çözümün sonuçtaki ASCII gösterimi. Boşlukları ve kraliçeleri temsil etmek için iki farklı ASCII değerini seçebilirsiniz. Yine, bu herhangi bir uygun biçimde (tek dize, bir dize listesi, bir karakter dizisi, vb.) Çıktılabilir.

kurallar

  • Öncü satırlar veya boşluk satırlarının tümü isteğe bağlıdır ve karakterlerin kendileri doğru hizalandığı sürece karakterler arasındaki boşluktur.
  • Kodunuz için daha golfçü olan olası konumları hesaplamak için bir algoritma kullanabilir veya açık "merdiven basamağı" çözüm stilini kullanabilirsiniz.
  • Tam bir program veya bir işlev kabul edilebilir. Bir işlev varsa, çıktıyı yazdırmak yerine döndürebilirsiniz.
  • Mümkünse, diğer kişilerin kodunuzu deneyebilmesi için lütfen bir çevrimiçi test ortamına bağlantı ekleyin!
  • Standart boşluklar yasaktır.
  • Bu bu nedenle her zamanki golf kuralları geçerlidir ve en kısa kod (bayt cinsinden) kazanır.

Örnekler

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
Tek girişler için test senaryoları verebilir misiniz?
Kritixi Lithos

@Cowsquack Eklendi n = 7 örnek
AdmBorkBork

1
@KeyuGan MATL yanıtı gibi bir şey mi? Evet bu iyi.
AdmBorkBork

2
@JonathanAllan Program bir olasılıkla sonlu sürede bitirildiği sürece (tüm başvurular için standart olarak) böyle bir hariç tutma amaçlanmamıştır.
AdmBorkBork

Yanıtlar:


5

MATL , 33 32 27 bayt

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

Çevrimiçi deneyin!

Yarı kaba kuvvet, belirleyici olmayan yaklaşım:

  1. Sıra konumlarının rastgele permütasyonunu oluşturma
  2. Sütun konumlarının rastgele permütasyonunu oluşturma
  3. Hiçbir kraliçenin diyagonal veya anti-diyagonal paylaşmadığını kontrol edin
  4. Gerekirse tekrarlayın.

Elde edilen çözelti rastgele. Kodu tekrar çalıştırırsanız, farklı bir geçerli yapılandırma alabilirsiniz. Çalışma süresi de rastgele, ancak en uzun test durumu ( n = 10) çoğu zaman TIO'da yaklaşık 30 saniye içinde bitiyor.


Her zaman doğru cevabı vermediği sürece bunun bir çözüm olarak sayıldığından emin değilim.
junkmail

1
@junkmail Huh? Diye bir şey yoktur , doğru cevap olarak (meydan okuma ile belirtildiği gibi) bir kaç çözümler. Kod her zaman verir , bir , sadece aynı değil her zaman doğru cevap
Luis Mendo

Teorik olarak, programın birçok kez keyfi olarak çalışması ve hala bir cevap verememesi mümkündür.
junkmail

1
@junkmail Ama bir olasılıkla sonlu sürede bitiyor
Luis Mendo

1
@JamesHollis Katılıyorum. Bu, bazı permütasyonların diğerlerinden daha muhtemel olmasını sağlayabilir, ancak herhangi bir permütasyonun görünmesini engellemez. Sonuçta çözüme ulaşılacaktır. Buna ek olarak, rastgele jeneratörün ideal olduğunu varsaymak genellikle kabul edilir
Luis Mendo

5

C, 114 bayt

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

Bir çözeltiyi doğrudan O (1) sürede yazdırır.


1
N kez tekrarlanan bir döngü ile O (1) nasıl olabileceği net değil. Tüm bu hesaplamalar her zaman sabit zamanda nasıl yapılabilir?
poi830

1
@ poi830 Kraliçenin pozisyonunu belirlemek için satır başına O (1) hesaplama süresi demek istiyorum.
orlp

için yeni bir değişken oluşturarak birkaç tasarruf edemediniz n/2mi?
Jeffmagma

Önermek n-=o=n%2;for(y=n+o;y--;) yerineo=n%2;n-=o;for(y=0;y<n+o;++y)
ceilingcat

2

Mathematica, 103 108 110 117 bayt

İçin -5 bayt DuplicateFreeQ->E!=##&@@@

-7 byte için ReplacePart[Array[],]->SparseArray[]

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

Bir 2D dizisi döndürün. Bu hesapla için 2.76s alır f[6]ve 135S f[7]. (Geçerli sürümde, -olur 0veQ olur 1.

output

Algoritma MATL cevabına benzer, ancak burada kod tamamen kaba kuvvettir.


1

C - 222 bayt

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

Kod benim değil IOCCC'den . Umarım herhangi bir kuralı ihlal etmem. Ayrıca, bu N için 4 ve 99 arasındaki tüm çözümleri görüntüler. Daha sonra bir TIO bağlantısı almaya çalışacağım.


Bu kod size ait olmadığından, bir Topluluk Wiki'sine dönüştürebilir misiniz? (düzenleme penceresinin altındaki "Topluluk Wiki" yazan düğmeyi tıklayın)
caird coinheringaahing

Merhaba QuaerendoInvenietis ve PPCG'ye hoş geldiniz. Şu anda yazıldığı gibi, bu sadece belirli bir sayıyı girdi ve çıktı olarak almıyor gibi görünüyor.
AdmBorkBork

1

Jöle , 24 21 bayt

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

Çevrimiçi deneyin!

Her bir kraliçenin ayrı satırlara yerleştirildiğini varsayarsak, yalnızca her bir kraliçenin, [1, 2, ..., n] ve test ederek gerekir.

açıklama

,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€yerine kullanamaz œc€2mısınız?
Outgolfer Erik

1

Python 3, 204 189 bayt

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

Bütün permütasyonlarda kaba kuvvet arama. * 'I kaldırabilir ve liste kavrayışlarını yazdırabilirim, ama korkunç görünüyorlar.

Çıktı:

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

Hafifçe soluksuz:

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 bayt

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

Çevrimiçi deneyin!

Bu, daha fazla ya da daha az dayanır Cı çözeltisi ile orlp .

açıklama

Yürütme yolları vurgulanmış kaynak kodu

*Stdin'den q , q sayısını okuyun ve daha sonra kullanmak üzere iki değişkeni hesaplayın: n = q - q%2ve hn = n/2
*ana döngüyü başlatın, r , satır numarasını q , döngü başlangıcında, azaltarak 0 aşağı ilk böylece r olduğu q, eksi 1
*hesaplama aşağıdaki formüle her satırda kraliçe ofset:

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

*Çıktı ofset daha kolay çıkış döngü yapar sırf uzay karakterler kraliçenin şimdiki satır için pozisyon, artı bir ek alan girinti için.
*ÇıktıQ sonrasında bir yeni satır kraliçe için, bir sonraki satıra geçmek için.
*Testi eğer r , aksi takdirde biz tekrar ana döngüyü tekrarlayın, gemiye sonuna ulaştınız ve çıkabilirsiniz bu durumda sıfırdır.


0

Haskell , 145 bayt

Açık kaba kuvvet yaklaşımı:

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

Çevrimiçi deneyin!


0

Retina , 136 bayt

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

Çevrimiçi deneyin! @ Orlp'nin mükemmel C cevabı. Açıklama:

.+
$* 

Boşlukları kullanarak tekliye dönüştürün (sonrasında boşluk vardır *).

$_;$`Q¶

Boşluk, a , sonra boşluk, sonra a Niçeren satırlar oluşturun . Kalan aşamalar tüm satırlara uygulanır.N;0..N-1Q

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

Tamsayı N2'ye bölün . (Ayrıca :;desenleri tutturmayı kolaylaştırmak için sonucu sarın .)

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

Döngü dizini eşitse N/2*2, o kadar çok boşluk bırakın.

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

Eğer N/23 katı olduğu daha sonra modülo çift döngü indeksi artı birini almayı N/2*2+1.

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

Aksi takdirde, devre indeksini iki katına ve artı (N/2-1)modulo'nun alt yarısında ekstra 3 alınız N/2*2.

( +)%\1?

Aslında modulo işlemini gerçekleştirin.


0

Kömür , 44 bayt

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

Çevrimiçi deneyin! Bağlantı, kodun ayrıntılı versiyonudur. @ Orlp'nin mükemmel C cevabının başka bir limanı.


0

APL (Dyalog Unicode) , 18 bayt SBCS

Tam program nstdin istemi . ·Boş kareler ve Kraliçeler için boşlukla ayrılmış çözümü stdout'a yazdırır .

CY'dfns'
queens

Çevrimiçi deneyin!

⎕CY'dfns'Cı- op y "dfns" kütüphane

 stdin'den girdi al

queens gerçekten benzersiz Queens'in çözümlerini bulun (yansıma veya dönüş yok)

 ilk çözümü seç


0

J , 49 bayt

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

Çevrimiçi deneyin!

Uzunluğu tüm permütasyonlarını test ederek kaba kuvvet n .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.