Yapboz Kraliçeleri doğrulayın


16

Eğer bir kraliçenin satrançta ne olduğunu bilmiyorsanız, bunun bir önemi yoktur; bu sadece bir isim :)

Girişiniz, bir miktar kraliçe içeren keyfi bir genişlik ve yükseklik karesi olacaktır . Giriş kartı şöyle görünecektir (bu kartın genişliği ve yüksekliği 8'dir):

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

Bu tahtada 8 kraliçe var. Burada 7 veya 1 veya 10 olsaydı, yönetim kurulu geçerli olmazdı.

Burada .boş bir alan Qiçin bir ve bir kraliçe için bir kullanıyoruz. Alternatif olarak, bunun yerine istediğiniz boşluk olmayan herhangi bir karakteri kullanabilirsiniz.

Bu giriş geçerli olarak doğrulanabilir ve doğru bir değer yazdırmanız (veya döndürmeniz) gerekir (geçerli değilse, bir yanlış değeri yazdırmanız (veya döndürmeniz)). Bu, hiçbir kraliçe diğeriyle aynı satır, sütun, diyagonal veya anti-diyagonalde olmadığından geçerlidir .

Örnekler (parantez içindeki şeyleri çıktılamayın):

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

1

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

0

Q.
Q.

0

..Q
...
.Q.

0 (this is 0 because there are only 2 queens on a 3x3 board)


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

1

Q

1 (this is valid, because the board is only 1x1, so there's no queen that can take another)

Bir girdinin yalnızca diğeriyle aynı satır, sütun, diyagonal veya anti-diyagonalde yoksa, geçerli olduğunu vurgulayayım .

kurallar

  • Asla boş bir giriş almayacaksınız
  • Giriş, kartın alanının sqaure kökünden daha az kraliçe içeriyorsa, geçerli değildir.
  • Bir 2x2 veya 3x3 kartı için geçerli bir çözüm bulunmadığını, ancak genişlik ve yüksekliğin doğal bir sayı olduğu diğer tüm kare levhalar için bir çözüm olduğunu unutmayın .
  • Giriş, PPCG kurallarına göre herhangi bir makul formatta olabilir
  • Giriş her zaman bir sqaure olacaktır
  • Örneklerde 1 ve 0 kullandım, ancak herhangi bir doğruluk veya yanlış değer kullanabilirsiniz ( Why yes, sir, that is indeed the caseve gibi Why no, sir, that is not the case)

Bu , en kısa kod kazanır!



1
Misiniz {(x, y, v)}ile vde [., Q]geçerli giriş biçimi olabilir mi?
PidgeyUsedGust

@DuctrTape Bunun çok mantıklı olduğunu düşünmüyorum.
Okx

2
@Okx Başka bir deyişle, girdi olarak bir koordinat ve değer listesi almak istiyorlar. Örneğin: (0, 0, Q), (0, 1, .), (1, 0, Q), (1, 1, .)üçüncü test durumu olurdu.
Mego

Satır sonu olmayan bir dize alabilir miyim?
Titus

Yanıtlar:


7

Salyangoz , 14 bayt

&
o.,\Q!(z.,\Q

Çevrimiçi deneyin!

2B karar sorunu için 2B desen eşleştirme dili gibi bir şey yok. :)

açıklama

&Birinci satırda girişi, muhtemel her konumda eşleştirmek için ikinci satırda desen gerektiren bir maç modu seçenektir. Bu durumda, program yazdırır 1, aksi takdirde yazdırır 0.

Desenin kendisine gelince ), sonunda bir örtük olduğunu unutmayın .

o       ,, Move in any orthogonal direction (up, down, left or right).
.,\Q    ,, Make sure that there's a Q somewhere in that direction from the
        ,, starting position of the match.
!(      ,, After finding the Q, make sure that the following part _doesn't_ match:
  z     ,,   Move in any orthogonal or diagonal direction.
  .,\Q  ,,   Try to find another Q in a straight line.
)

Bunun neden işe yaradığını görmek için en kolayı, negatif ileriye doğru başlayarak: zaten bulduğumuz Qdiğerinden düz bir çizgi Qolmadığından emin olarak, N kraliçesinden daha fazla olmadığından emin oluruz (aksi takdirde, bir satırda iki olmak ve bu kraliçeleri başka bir tane bulmadan bulmak mümkün olmaz). Daha sonra, birinci bölüm, herhangi bir konumdan dik bir yönde ulaşılabilen bir kraliçenin olduğundan emin olmak, tam olarak N kraliçelerinin olmasını sağlar. Biri eksik olsaydı, bir kraliçe olmadan bir satır ve bir sütun olurdu. Bunların kesişiminden başlayarak, sadece dik bir yöne giderek bir kraliçe bulmak mümkün olmazdı.


6

Jöle , 17 veya 15 bayt

ỴµUŒD;ŒD;ZVṀ;V=1Ṃ

Çevrimiçi deneyin!

Bir kraliçe ve ¹boşluk için kullanır . (Bu çoğunlukla girdiyi dizi olarak alma yasağının bir sonucudur, çünkü girdiyi dize olmaya zorlar; Jelly'de dizeleri tamsayılara dönüştürmek zordur, en kolay yöntem değerlendirilir ve 1 yerine bunun yerine 0, "add 1" ( ) ve "add 0" ( ¹) kullanarak birkaç toplamı ve harita talimatını atlamayı mümkün kılar, çünkü bir listedeki kraliçeleri değerlendirerek sayabiliriz.) Doğruluk ve falsey değerleri Jelly'in normal 1ve 0.

DÜZENLEME: Soru, matris olarak girdi almaya izin vermek için bu yanıtı yazdığımdan beri değiştirildi. Bu, Ỵµ2 baytlık tasarruf sağlayarak öncüyü düşürmeye izin verir . Ayrıca, giriş biçimini değerlendirmek Syerine toplamı kullanarak daha normal bir şeye değiştirmeye izin verir V, ancak baytları kurtardığını düşünmüyorum ve bu korkak biçimi sevdim.

açıklama

ỴµUŒD;ŒD;ZVṀ;V=1Ṃ
Ỵ                    Split on newlines.
 µ                   Set this value as the default for missing arguments.
     ;  ;            Concatenate the following three values:
  UŒD                - the antidiagonals;
      ŒD             - the diagonals;
         Z           - and the columns.
          V          Evaluate (i.e. count the queens on) all of those.
           Ṁ         Take the largest value among the results.
            ;V       Append the evaluation (i.e. queen count) of {each row}.
              =1     Compare each value to 1.
                Ṃ    Take the minimum (i.e. most falsey) result.

Temel fikir şu ki, her bir antidiagonal, diyagonal ve sütun üzerinde en fazla bir kraliçe olmasını sağlıyoruz; ve her sırada tam bir kraliçe. Bu koşullar, dört tür hattın her birinde en fazla bir kraliçe ve tahtanın yan uzunluğuna eşit sayıda kraliçe olmasını gerektirecek kadar birliktedir.

Bu arada, Jelly muhtemelen antidiagonaller için yerleşik bir şeyle yapabilirdi, ancak AFAICT'de bir tane yok gibi görünüyor, bu yüzden tahtayı yansıtmak ve sonra köşegenleri almak için razı olmalıyım.

Bir başka ilginç not, (hepsi eşit) olarak değiştirmenin =1Ṃ, her satırın, sütunun, diyagonal ve antidiagonun k kraliçesinden fazla olmadığı ve pano tam olarak içerdiği bir n × n panosunu kabul edecek olan Egenelleştirilmiş bir n -queens denetleyicisi vermesidir. kn kraliçeler. Kısıtlama k eşit 1'e aslında iki bayt mal oldu.


Kurallar güncellendi, şimdi "Giriş PPCG kurallarına göre herhangi bir makul formatta olabilir", bu onu kısaltmak gerekir :) DÜZENLEME - Ben bunu fark gördüm.
Jonathan Allan

5

Oktav, 57 70 67 51 52 bayt

Kullanılarak 1 byte Kaydedilen flipyerine rot90@LuisMendo sayesinde, ancak 1x1 davayla ilgili bir hata buldum

@(A)all(sum([A A' (d=@spdiags)(A) d(flip(A))],1)==1)

Girdi, 1'i bir Kraliçeyi ve 0, boş bir alanı temsil eden ikili bir matris olarak alır.

İlk olarak giriş matrisini ve onun aktarımını birleştiren anonim bir işlev oluşturur.

spdiagsargümanlarla aynı sayıda satıra sahip bir matris oluşturur, köşegenler sütunlara dönüştürülür (gerekirse sıfır dolgulu), bu nedenle spdiagsköşegenleri almak için giriş matrisini spdiagsve antidiagonalleri almak için yatay olarak çevrilmiş matrisi birleştirin.

Şimdi birleştirilmiş matrisin her sütununun toplamını alın ve her sütunun tam olarak 1 olduğundan emin olun.

İdeone üzerinde örnek çalışma .


Sanırım bunun flipyerine kullanabilirsinizrot90
Luis Mendo

@LuisMendo Evet, bu da işe yarayacak. Teşekkürler!
beher

Ayrıca, kaçınamaz all()mısın?
Luis Mendo

@LuisMendo Ugh ... muhtemelen ... ama akşam yemeğinden sonra beklemek zorunda kalacak;)
beher

4

MATL , 38 34 bayt

4 bayt kapalı @Beaker !

sG!sGt&n_w&:&XdsGP5M&Xdsv2<GnGzU=*

Girdi, noktalı virgüllerin satır ayırıcıları olarak kullanıldığı 2B sıfır ve sıfır dizisidir.

Bu doğruluk olarak bir sütun vektörü ve falsi olarak en az bir sıfır içeren bir sütun vektörü çıkarır.

Çevrimiçi deneyin!Altbilgi kodu, ifdoğruluk veya sahtelik gösteren bir daldır.

Veya tüm test doğrulayın .

açıklama

s      % Input binary matrix implicitly. Sum of columns. Gives a row vector
G!     % Paste input again. Transpose
s      % Sum of columns (rows in the original matrix). Gives a row vector
G      % Paste input again
t&n    % Duplicate. Push number of rows and number of columns (will be equal)
_w     % Negate, flip
&:     % Binary range. Gives [-n -n+1 ... n] for input of size n×n
&Xd    % Get diagonals -n through n. This gives all diagonals as colums
s      % Sum of each column (diagonals of original matrix). Gives a row vector
GP     % Paste input again. Flip vertically
5M     % Push [-n -n+1 ... n] again
&Xd    % Get diagonals -n through n (anti-diagonals of original matrix)
s      % Sum of each column. Gives a row vector
v      % Concatenate everything into a column vector
2<     % True for elements that are less than 2
Gn     % Paste input again. Number of elements
Gz     % Paste input again. Number of nonzeros (i.e. of queens)
U      % Square
=      % True if equal
*      % Mutiply, element-wise

Giriş olarak ikili bir matris alabileceğiniz için 2 bayt kaydedebilirsiniz.
beher

2

J , 37 bayt

(+/&,=#)*1=[:>./+//.,+//.&|.,+/,+/&|:

Boole matrisini argüman olarak alan anonim fonksiyon treni.

Çevrimiçi deneyin!

( +/toplamı &ait ,ravel =eşittir #satır çetelesini)

* ve (lit. kez)

1biri =eşittir maksimum[:>./

+/toplamları /.çapraz olarak ,ve (aydınlatılmış)

+/toplamları /.çapraz &bir |.arka ,ve

+/toplamlar ,ve

+/toplamları &ve |:devrik


2

SnakeEx , 67 bayt

m:({q<>}({q<R>}[{q<RF>}{n<RF>}].)*{e<>}<R>)%{4}
e:.$
q:_*Q_*$
n:_+$

Kullanımları _Yerine. girişte. Doğruluk için 1 veya daha fazla eşleşme, falsey için 0 eşleşme döndürür. Başlıkta yer alan bağlantıda bir çevrimiçi tercüman bulabilirsiniz.

açıklama

SnakeEx, 2 Boyutlu Desen Eşleştirme zorluğunun bir dilidir . Izgara eşleşen şeyler etrafında hareket "yılan" tanımlar. Yılanlar diğer yılanları üreterek dili oldukça güçlü hale getirebilir.

Bu programa aşağıdan yukarıya bakalım.

n:_+$

Bu, n1 veya daha fazla alt çizgiyle ve ardından ızgaranın kenarıyla eşleşen bir yılan tanımlar . Bunun 8 kardinal yönün herhangi birinde olabileceğine dikkat edin - yön, yılan doğduğunda belirlenir.

q:_*Q_*$

nYukarıdakine benzer şekilde , bu, qherhangi bir sayıda alt çizgi, tek Q, herhangi bir alt çizgi ve ızgaranın kenarıyla eşleşen bir yılan olarak tanımlar . Başka bir deyişle, içinde sadece bir kraliçe olan bir satır / sütun / köşegen.

e:.$

e bir karaktere ve ızgaranın kenarına uyan bir yılan.

m:({q<>}({q<R>}[{q<RF>}{n<RF>}].)*{e<>}<R>)%{4}

Ana yılan m bu yapı taşlarını tüm tahtayı kontrol etmek için kullanır. Kavramsal olarak, tüm sütunların ve satırların tam olarak bir kraliçeye sahip olduğunu ve tüm köşegenlerin en fazla bir kraliçeye sahip olup olmadığını kontrol etmek için diğer yılanları yumuşatarak ızgaranın dış kenarlarında dolaşır. Eğer ortaya çıkan yılanlardan herhangi biri eşleşmezse, tüm eşleşme başarısız olur. Hadi yıkalım.

  • ( )%{4}her iki taraf için bir kez olmak üzere parantezin içindekileri 4 kez çalıştırır. (Aşağıda, belirli bir tarafı resmetmek yararlıdır - örneğin, sol üst köşeden başlayıp sağa doğru hareket ederek ızgaranın üst kenarı.)
  • {q<>}qana yılanın hareket ettiği yöne doğru bir yılan üretir . Bu, geçerli kenarın "tam olarak bir kraliçe" kuralını karşıladığını doğrular. Yumurtlanan yılanların ana yılanın maç işaretçisini hareket ettirmediğini unutmayın, bu yüzden hala kenarın başındayız.
  • ( )* parantez içerisindeki öğelerin 0 veya daha fazlasıyla eşleşir.
  • {q<R>}qana yılanın yönünden sağa dönmüş bir yılan doğurur. (Örneğin, ana yılan üst kenar boyunca sağa doğru hareket ediyorsa, bu yılan aşağı doğru hareket eder.) Bu, her sütunu / satırı kontrol eder.
  • [ ] köşeli parantez içindeki seçeneklerden biriyle eşleşir:
    • {q<RF>}ana yılanın yönünden q45 derece sağa (yani sağ Rve Fsol) dönen bir yılan ortaya çıkarır. qDiyagonal tam olarak bir kraliçe içeriyorsa yılan eşleşir.
    • {n<RF>}nonun yerine bir yılan doğurur . nDiyagonal hiçbir kraliçeleri içeriyorsa yılan eşleşir.
  • . herhangi bir karakteri eşleştirir, eşleşme işaretçisini ileriye taşır.
  • Mümkün olduğunca çok yatay ve köşegenleri kontrol ettikten sonra, yumurtlayarak uçurumda olduğumuzu doğrularız {e<>}.
  • Son olarak, <R>ana yılanı sağa çevirir, bir sonraki kenara uymaya hazır.

Garip şeyler

  • Programda eşleştirmenin bir dış köşede başlamasını sağlayacak hiçbir şey yoktur. Aslında, doğru test senaryoları, bazıları içten bir yerde başlayan birkaç eşleşme verir. Buna rağmen, denediğim falsey vakalarının hiçbiri yanlış pozitif üretmedi.
  • Eğer dil spesifikasyonunu doğru okuyorsam, Xyerine (tüm çapraz yönlerde dal) kullanabilmeliydim RF. Ne yazık ki, çevrimiçi tercüman bunun bir sözdizimi hatası olduğunu söyledi. Ben de denedim *(her yöne dal), ama bu tercümanı astı.
  • Teorik olarak, _*Q?_*$diyagonallerde "en fazla bir kraliçeyi" eşleştirmek için çalışmak gibi bir şey olmalı, ancak bu da tercümanı astı. Tahminimce boş eşleşme olasılığı sorunlara yol açıyor.

2

Ruby, 120 bayt

Lambda işlevi, bir dize olarak girdi gerektiren orijinal spesifikasyonu temel alır.

->s{t=k=0
a=[]
s.bytes{|i|i>65&&(a.map{|j|t&&=((k-j)**4).imag!=0};a<<k)
k=i<11?k.real+1:k+?i.to_c}
t&&~a.size**2>s.size}

Q'ları karmaşık sayılara dönüştürür ve birbirinden çıkarır. İki kraliçenin koordinatları arasındaki fark yatay, dikey veya çapraz ise, onu 4. güce yükseltmek gerçek bir sayı verir ve düzenleme geçersiz olur.

Test programında yönlendirilmemiş

f=->s{                                 #Take input as string argument.
  t=k=0                                #k=coordinate of character. t=0 (truthy in ruby.)
  a=[]                                 #Empty array for storing coordinates.
  s.bytes{                             #Iterate through all characters as bytes.
    |i|i>65&&(                         #If alphabetical, compare the current value of k to the contents of a
      a.map{|j|t&&=((k-j)**4).imag!=0} #If k-j is horizontal, vertical or diagonal, (k-j)**4 will be real and t will be false
      a<<k)                            #Add the new value of k to the end of a.
    k=i<11?k.real+1:k+?i.to_c          #If not a newline, increment the imaginary part of k. If a newline, set imaginary to 0 and increment real
  }                                    #s.size should be a*a + a newlines. ~a.size = -1-a.size, so ~a.size**2 = (a.size+1)**2
t&&~a.size**2>s.size}                  #compare a.size with s.size and AND the result with t. Return value. 


p f["...Q....
......Q.
..Q.....
.......Q
.Q......
....Q...
Q.......
.....Q.."]

p f["...Q.
Q....
.Q...
....Q
..Q.."]

p f["Q.
Q."]

p f["..Q
...
.Q."]

p f["..Q.
Q...
...Q
.Q.."]

p f["Q"]

2

Python 3 , 232 , 200 155 bayt

d=1
f=input()
Q=[]
for i in f:d=[0,d][i.count('Q')==1];Q+=[(len(Q),i.index('Q'))]
print[0,d][sum(k[1]==i[1]or sum(k)==sum(i)for k in Q for i in Q)==len(Q)]

Çevrimiçi deneyin!

@Beaker giriş özelliklerinde bir değişiklik fark ederek -32 bayt; Dili Python 3'ten 2'ye değiştirdim, böylece inputbir dizi veya karakter dizisi dizisi olarak girdi almamı sağlıyorum .

@Leaky Nun sayesinde -45 bayt


Bu size yardımcı oluyorsa, giriş gereksinimleri gevşetilmiştir.
beher

@beaker Tamam, teşekkürler. Bunun yerine girdi dizeleri dizisi olarak alacağım. Bunu işaret ettiğiniz için teşekkürler!
HyperNeutrino


1

JavaScript (ES6), 115 bayt

a=>!a.some((b,i)=>b.some((q,j)=>q&&h[i]|v[j]|d[i+j]|e[i-j]|!(h[i]=v[j]=d[i+j]=e[i-j]=1))|!h[i],h=[],v=[],d=[],e=[])

Ungolfed:

function queens(arr) {
    horiz = [];
    vert = [];
    diag = [];
    anti = [];
    for (i = 0; i < arr.length; i++) {
        for (j = 0; j < arr.length; j++) {
            if (arr[i][j]) { // if there is a queen...
                if (horiz[i]) return false; // not already on the same row
                if (vert[j]) return false; // or column
                if (diag[i + j]) return false; // or diagonal
                if (anti[i - j]) return false; // or antidiagonal
                horiz[i] = vert[j] = diag[i + j] = anti[i - j] = true; // mark it
            }
        }
        if (!horiz[i]) return false; // fail if no queen in this row
    }
    return true;
}

0

Ruby, 155 bayt

->x{(y=x.map{|r|(i=r.index ?Q)==r.rindex(?Q)?i:p or-2}).zip(y.rotate).map.with_index{|n,i|n.max-n.min==1&&i<y.size-1?-2:n[0]}.inject(:+)*2==(s=x.size)*~-s}

Bu okumak korkunç, bu yüzden aşağıda biraz daha az golf versiyonum var

->x{
    (y=x.map{|r|(i=r.index ?Q)==r.rindex(?Q)?i:p or-2})
    .zip(y.rotate)
    .map.with_index{|n,i|n.max-n.min==1&&i<y.size-1?-2:n[0]}
    .inject(:+)*2==(s=x.size)*~-s
}

Bu aynı kod, ancak olanları ayırmak için bazı yeni satırlarla.

Tself kodu, dizede ( x) biçiminde bir dizi alan anonim bir lambda işlevidir ["..Q", "Q..", ".Q."].

İlk satır, her bir dizeyi o dizedeki Q karakterinin diziniyle eşleştirmektir. Q karakteri yoksa, yerine -2 1 gelir . Bu yeni dizin dizisi değişkene atanır y.

Bir sonraki satır, bu indeks dizisini kendisi tarafından bir (döndürülmüş) kaydırılarak sıkıştırır. Bu bir dizi ardışık indeks çifti ile sonuçlanır.

Bir sonraki satır özellikle karmaşık. Her bir endeks çiftinden geçer ve daha küçük olanı daha büyük olandan çıkarır. Bu 1 ise (ve son çift 2'de değiliz) ), aynı çaprazda olan iki kraliçe vardır ve -2 değeri eklenir, aksi takdirde dizedeki kraliçenin orijinal dizini eklenir .

Son satır, her biri için tüm dizinleri toplar ve n-1 için üçgen numarası olup olmadığını kontrol eder; burada n, karenin genişliği (veya yüksekliği) olup olmadığını kontrol eder.

1: -1 benim yolum olurdu, ama 0 dışında 1, bu yüzden diyagonallerin kontrolünü bozar. Nihai toplamı yanlış yapmak bunun olumsuzluğu önemlidir. 9 gibi yüksek bir sayı (tek basamaklı) düşündüm, ancak bunun yanlış bir doğrulamaya neden olmayacağından emin olamıyorum.
2: Tahta yuvarlak sarmaz, oysa ruby'nin rotatedizi işlevi yapar ve son çift bir farklıysa fark etmez - bu bir köşegen değildir.


0

PHP, 137 143 bayt

Neil'in çözümünden ilham aldı

for($n=1+strlen($s=$argv[1])**.5|0;($c=$s[$p])&&!(Q==$c&&$v[$x=$p%$n]++|$h[$x=$p/$n]++|$d[$y-$x]++|$a[$y+$x]++);$p++);echo$n-1==count($a)&&!$c;

ilk komut satırı bağımsız değişkeninden girdi alır; ile çalıştırın -r. Tek baytlık satır sonları gerektirir.
Aslında 0satır sonu dışında herhangi bir karakteri kullanabilirsiniz .
true ( 1) veya false (boş dize) yazdırır .

Yıkmak

for($n=1+strlen($s=$argv[1])**.5|0; // copy input to $s, $n=size+1 (for the linebreak)
    ($c=$s[$p])&&!(                 // loop through characters
        Q==$c&&                         // if queen: test and increment lines
            $v[$x=$p%$n]++|$h[$x=$p/$n]++|$d[$y-$x]++|$a[$y+$x]++
    );                                  // break if a line had been marked before
    $p++);
echo$n-1==count($a)             // print result: true for $n-1(=size) marks
    &&!$c;                      // and loop has finished

0

Piton 3 , 185 176 175 172 171 bayt

lambda x,c=lambda x:x.count("Q")==1:all([*map(c,x+[[l[i]for l in x]for i in range(len(x[0]))])])*~any(map(lambda s:"Q%sQ"%(s*".")in"".join(x),[len(x[0]),len(x[0])-2]))==-1

Dizge listesini girdi olarak alan anonim bir işlev.

Python 2 , 175 bayt

lambda x:all([a.count("Q")==1for a in x]+[[l[i]for l in x].count("Q")==1for i in range(len(x[0]))]+[all(map(lambda s:"Q%sQ"%(s*".")not in"".join(x),[len(x[0]),len(x[0])-2]))])
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.