Puzzle N-Queens

17

(Malgré plus de 60 questions sur les , nous n'avons pas de simple défi n-queens.)

Aux échecs, le puzzle N-Queens est décrit comme suit: étant donné un n x néchiquier et des nreines, placez les reines sur l'échiquier de sorte qu'il n'y ait pas deux reines qui se menacent. Voici un exemple de solution pour n = 8, emprunté à Wikipedia.

Exemple de solution à 8 reines de Wikipedia

Ou, en rendu ASCII:

xxxQxxxx
xxxxxxQx
xxQxxxxx
xxxxxxxQ
xQxxxxxx
xxxxQxxx
Qxxxxxxx
xxxxxQxx

Le défi ici sera de prendre en entrée net en sortie une représentation ASCII d'une solution au npuzzle -Queens. Puisqu'il y a plus d'une solution possible (par exemple, au moins, une rotation ou une réflexion), votre code n'a besoin que de générer une solution valide.

Contribution

Un seul entier positif navecn >= 4 dans un format pratique . (n = 2 et n = 3 n'ont pas de solutions, et n = 1 est trivial, donc celles-ci sont exclues)

Production

La représentation ASCII résultante d'une solution au casse-tête des N-reines, comme indiqué ci-dessus. Vous pouvez choisir deux valeurs ASCII distinctes pour représenter les espaces vides et les reines. Encore une fois, cela peut être sorti dans n'importe quel format approprié (chaîne unique, liste de chaînes, tableau de caractères, etc.).

Règles

  • Les sauts de ligne ou les espaces de début ou de fin sont tous facultatifs, ainsi que les espaces entre les caractères, tant que les caractères eux-mêmes s'alignent correctement.
  • Vous pouvez soit utiliser un algorithme pour calculer les positions possibles, soit utiliser le style de solution explicite "en escalier", selon le golfeur de votre code.
  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Si possible, veuillez inclure un lien vers un environnement de test en ligne afin que d'autres personnes puissent essayer votre code!
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.

Exemples

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
AdmBorkBork
la source
1
En relation.
2017 totalement humain
1
Pourriez-vous donner des tests pour des entrées impaires?
Kritixi Lithos
@Cowsquack Ajouté n = 7 exemple
AdmBorkBork
1
@KeyuGan Quelque chose comme la réponse MATL? Oui c'est bien.
AdmBorkBork
2
@JonathanAllan Aucune exclusion de ce type n'était prévue, tant que le programme se termine dans un temps fini avec une probabilité (comme standard pour toutes les soumissions).
AdmBorkBork

Réponses:

5

MATL , 33 32 27 octets

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

Essayez-le en ligne!

Force semi-brute, approche non déterministe:

  1. Générer une permutation aléatoire des positions des lignes
  2. Générer une permutation aléatoire des positions des colonnes
  3. Vérifiez qu'aucune reine ne partage une diagonale ou une anti-diagonale
  4. Répétez si nécessaire.

La solution obtenue est aléatoire. Si vous exécutez à nouveau le code, vous pouvez obtenir une configuration valide différente. Le temps d'exécution est également aléatoire, mais le cas de test le plus long ( n = 10) se termine en environ 30 secondes dans TIO la plupart du temps.

Luis Mendo
la source
Je ne suis pas sûr que cela compte comme une solution, car il ne donne pas toujours la bonne réponse.
junkmail
1
@junkmail Huh? Il n'y a rien de tel que la bonne réponse, car il existe plusieurs solutions (comme indiqué par le défi). Le code donne toujours une réponse correcte, mais pas la même à chaque fois
Luis Mendo
Il est théoriquement possible que le programme s'exécute arbitrairement plusieurs fois et ne donne toujours pas de réponse.
junkmail
1
@junkmail Mais cela se termine en temps fini avec une probabilité
Luis Mendo
1
@JamesHollis Je ne suis pas d'accord. Cela pourrait rendre certaines permutations plus probables que d'autres, mais cela n'empêcherait aucune permutation d'apparaître. La solution serait donc finalement trouvée. Et en plus, supposer que le générateur aléatoire est idéal est généralement accepté
Luis Mendo
5

C, 114 octets

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

Imprime directement une solution en temps O (1).

orlp
la source
1
Il n'est pas clair pour moi comment cela peut être O (1) avec une boucle se répétant n fois. Comment tous ces calculs peuvent-ils toujours être effectués en temps constant?
poi830
1
@ poi830 Je veux dire O (1) temps de calcul par ligne pour déterminer la position de la reine.
orlp
ne pourriez-vous pas en enregistrer quelques-unes en créant une nouvelle variable pour n/2?
Jeffmagma
Suggérer à la n-=o=n%2;for(y=n+o;y--;)place deo=n%2;n-=o;for(y=0;y<n+o;++y)
plafondcat
2

Mathematica, 103 108 110 117 octets

-5 octets pour DuplicateFreeQ->E!=##&@@@

-7 octets pour ReplacePart[Array[],]->SparseArray[]

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

Renvoie un tableau 2D. Il faut 2,76 secondes pour calculer f[6]et 135 secondes pour f[7]. (Dans la version actuelle, -devient 0et Qà 1.

production

L'algorithme est similaire à la réponse MATL mais ici le code est complètement brutal.

Keyu Gan
la source
1

C - 222 octets

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

Le code n'est pas le mien, mais celui de l' IOCCC . J'espère que je n'enfreins aucune règle. En outre, cela affiche toutes les solutions pour N entre 4 et 99. J'essaierai d'obtenir un lien TIO plus tard.

QuaerendoInvenietis
la source
Comme ce code n'est pas le vôtre, pourriez-vous le convertir en un wiki communautaire? (cliquez simplement sur le bouton sous la fenêtre d'édition qui dit "Community Wiki")
caird coinheringaahing
Salut QuaerendoInvenietis et bienvenue à PPCG. Tel qu'il est actuellement écrit, cela ne semble pas prendre un nombre particulier en entrée et en sortie uniquement pour cette solution.
AdmBorkBork
1

Gelée , 24 21 octets

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

Essayez-le en ligne!

En supposant que chaque reine est placée sur des rangées distinctes, il nous suffit de trouver les indices de colonne où placer chaque reine pour éviter les conflits, qui peuvent être trouvés en générant une permutation aléatoire [1, 2, ..., n]et en la testant.

Explication

,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
miles
la source
Vous ne pouvez pas utiliser Œc€au lieu de œc€2pour -1?
Erik the Outgolfer du
1

Python 3, 204 189 octets

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

Recherche de force brute à travers toutes les permutations. Je pourrais supprimer le * et imprimer la liste des compréhensions, mais elles ont l'air horribles.

Production:

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

Légèrement non golfé:

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
James Hollis
la source
1

Befunge, 122 octets

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

Essayez-le en ligne!

Ceci est plus ou moins basé sur la solution C par orlp .

Explication

Code source avec les chemins d'exécution mis en évidence

*Lisez le nombre de reines, q , à partir de stdin et calculez deux variables pour une utilisation ultérieure:, n = q - q%2et hn = n/2
*démarrez la boucle principale, en itérant r , le numéro de ligne, de q vers le bas à 0, décrémentant au début de la boucle, donc le premier r est q moins 1.
*Calculez le décalage de la reine dans chaque rangée avec la formule suivante:

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

*Générez des caractères d'espace de décalage pour indenter la position de la reine pour la ligne actuelle, plus un espace supplémentaire simplement parce que cela facilite la boucle de sortie.
*Sortez le Qpour la reine, suivi d'un retour à la ligne pour passer à la ligne suivante.
*Testez si r est zéro, auquel cas nous avons atteint la fin de la carte et pouvons quitter, sinon nous répétons la boucle principale à nouveau.

James Holderness
la source
0

Haskell , 145 octets

L'approche évidente de la force brute:

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

Essayez-le en ligne!

ბიმო
la source
0

Rétine , 136 octets

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

Essayez-le en ligne! Port de l'excellente réponse C de @ orlp. Explication:

.+
$* 

Convertir en unaire, en utilisant des espaces (il y a un espace après le *).

$_;$`Q¶

Créez des Nlignes avec des Nespaces, a ;, puis des 0..N-1espaces, puis a Q. Les étapes restantes s'appliquent à toutes les lignes.

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

Entier diviser Npar 2. (Envelopper également le résultat :;pour faciliter l'ancrage des motifs.)

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

Si l'index de boucle est égal N/2*2, laissez simplement autant d'espaces.

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

Si N/2est un multiple de 3, alors prenez le double de l'index de boucle plus un, modulo N/2*2+1.

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

Sinon, prenez le double de l'index de boucle (N/2-1)plus un 3 supplémentaire dans la moitié inférieure de la planche, modulo N/2*2.

( +)%\1?

Effectuez en fait l'opération modulo.

Neil
la source
0

Fusain , 44 octets

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

Essayez-le en ligne! Le lien est vers la version détaillée du code. Un autre port de l'excellente réponse C de @ orlp.

Neil
la source
0

APL (Dyalog Unicode) , 18 octets SBCS

Programme complet ndemandant de stdin. Imprime la solution séparée par des espaces vers la sortie standard en utilisant ·pour les carrés vides et pour les reines.

CY'dfns'
queens

Essayez-le en ligne!

⎕CY'dfns'C op y la bibliothèque "DFNS"

 obtenir des informations de stdin

queens trouver toutes les solutions vraiment uniques de Queens (pas de reflets ni de rotations)

 choisissez la première solution

Adam
la source
0

J , 49 octets

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

Essayez-le en ligne!

Force brute en testant toutes les permutations de longueur n .

miles
la source