N-Queens Puzzle

17

(A pesar de más de 60 preguntas etiquetadas , no tenemos un simple desafío n-reinas).

En ajedrez, el Rompecabezas N-Queens se describe de la siguiente manera: dado un n x ntablero de ajedrez y nreinas, coloque las reinas en el tablero de modo que no haya dos reinas amenazándose entre sí. A continuación se muestra una solución de ejemplo n = 8, tomada de Wikipedia.

Solución de ejemplo de 8 reinas de Wikipedia

O, en la representación ASCII:

xxxQxxxx
xxxxxxQx
xxQxxxxx
xxxxxxxQ
xQxxxxxx
xxxxQxxx
Qxxxxxxx
xxxxxQxx

El desafío aquí será tomar la entrada ny salida de una representación ASCII de una solución para el nrompecabezas -Queens. Dado que hay más de una solución posible (por ejemplo, al menos, una rotación o reflexión), su código solo necesita generar una solución válida.

Entrada

Un solo entero positivo ncon n >= 4 cualquier formato conveniente . (n = 2 yn = 3 no tienen soluciones, y n = 1 es trivial, por lo que están excluidos)

Salida

La representación ASCII resultante de una solución para el rompecabezas N-reinas, como se describe anteriormente. Puede elegir dos valores ASCII distintos para representar espacios en blanco y reinas. Una vez más, esto se puede generar en cualquier formato adecuado (cadena única, una lista de cadenas, una matriz de caracteres, etc.).

Reglas

  • Las nuevas líneas iniciales o finales o espacios en blanco son opcionales, así como los espacios en blanco entre caracteres, siempre que los caracteres se alineen correctamente.
  • Puede usar un algoritmo para calcular las posibles posiciones, o usar el estilo explícito de solución de "escalón", el que sea más apropiado para su código.
  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • Si es posible, incluya un enlace a un entorno de prueba en línea para que otras personas puedan probar su código.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

Ejemplos

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
fuente
1
Relacionado.
totalmente humano
1
¿Podría dar casos de prueba para entradas impares?
Kritixi Lithos
@Cowsquack Agregado n = 7 ejemplo
AdmBorkBork
1
@KeyuGan ¿Algo así como la respuesta MATL? Si, esta bien.
AdmBorkBork
2
@JonathanAllan No se pretendía tal exclusión, siempre que el programa finalice en tiempo finito con probabilidad uno (como estándar para todas las presentaciones).
AdmBorkBork

Respuestas:

5

MATL , 33 32 27 bytes

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

Pruébalo en línea!

Fuerza semi-bruta, enfoque no determinista:

  1. Generar una permutación aleatoria de posiciones de fila.
  2. Generar una permutación aleatoria de posiciones de columna.
  3. Comprueba que ninguna de las reinas comparte una diagonal o anti-diagonal
  4. Repita si es necesario.

La solución obtenida es aleatoria. Si vuelve a ejecutar el código, puede obtener una configuración válida diferente. El tiempo de ejecución también es aleatorio, pero el caso de prueba más largo ( n = 10) termina en aproximadamente 30 segundos en TIO la mayor parte del tiempo.

Luis Mendo
fuente
No estoy seguro de que esto cuente como una solución, dado que no siempre da la respuesta correcta.
correo basura
1
@junkmail ¿Eh? No existe la respuesta correcta, ya que hay varias soluciones (como lo indica el desafío). El código siempre da una respuesta correcta, pero no siempre es la misma
Luis Mendo
Teóricamente es posible que el programa se ejecute arbitrariamente muchas veces y aún así no pueda dar una respuesta.
correo basura
1
@junkmail Pero termina en tiempo finito con probabilidad uno
Luis Mendo
1
@JamesHollis No estoy de acuerdo. Eso podría hacer que algunas permutaciones sean más probables que otras, pero no evitaría que aparezca ninguna permutación. Entonces, finalmente se alcanzaría la solución. Y además, asumir que el generador aleatorio es ideal es generalmente aceptado
Luis Mendo
5

C, 114 bytes

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 directamente una solución en O (1) tiempo.

orlp
fuente
1
No me queda claro cómo puede ser O (1) con un bucle que se repite n veces. ¿Cómo se pueden hacer todos esos cálculos siempre en tiempo constante?
poi830
1
@ poi830 Me refiero a O (1) tiempo de cálculo por fila para determinar la posición de la reina.
orlp
¿no podrías ahorrar algunos haciendo una nueva variable para n/2?
Jeffmagma
Sugerir en n-=o=n%2;for(y=n+o;y--;)lugar deo=n%2;n-=o;for(y=0;y<n+o;++y)
ceilingcat
2

Mathematica, 103 108 110 117 bytes

-5 bytes para DuplicateFreeQ->E!=##&@@@

-7 bytes para ReplacePart[Array[],]->SparseArray[]

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

Devuelve una matriz 2D. Se necesitan 2.76s para calcular f[6]y 135s para f[7]. (En la versión actual, se -convierte en 0y Qpara 1.

salida

El algoritmo es similar a la respuesta MATL pero aquí el código es completamente fuerza bruta.

Keyu Gan
fuente
1

C - 222 bytes

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

El código no es mío, sino de IOCCC . Espero no estar rompiendo ninguna regla. Además, esto muestra todas las soluciones para N entre 4 y 99. Trataré de obtener un enlace TIO más adelante.

QuaerendoInvenietis
fuente
Como este código no es suyo, ¿podría convertirlo en un Wiki de la comunidad? (simplemente haga clic en el botón debajo de la ventana de edición que dice "Community Wiki")
caird coinheringaahing
Hola QuaerendoInvenietis y bienvenidos a PPCG. Como está escrito actualmente, esto no parece tomar un número particular como entrada y salida solo como esa solución.
AdmBorkBork
1

Gelatina , 24 21 bytes

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

Pruébalo en línea!

Suponiendo que cada reina se coloque en filas separadas, solo necesitamos encontrar los índices de columna para colocar a cada reina para evitar conflictos, que se pueden encontrar generando una permutación aleatoria de [1, 2, ..., n] y probándola.

Explicació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
millas
fuente
¿No puedes usar en Œc€lugar de œc€2para -1?
Erik the Outgolfer
1

Python 3, 204 189 bytes

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úsqueda de fuerza bruta a través de todas las permutaciones. Podría eliminar el * e imprimir la lista de comprensiones, pero se ven horribles.

Salida:

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

Ligeramente incólume:

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
fuente
1

Befunge, 122 bytes

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

Pruébalo en línea!

Esto se basa más o menos en la solución C de orlp .

Explicación

Código fuente con rutas de ejecución resaltadas

* *Lea el número de reinas, q , de stdin y calcule dos variables para su uso posterior: n = q - q%2e inicie el bucle hn = n/2
* *principal, iterando r , el número de fila, de q a 0, disminuyendo al inicio del bucle, por lo que el primer r es q menos 1.
* *Calcula el desplazamiento de la reina en cada fila con la siguiente fórmula:

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

* *Salida de caracteres de espacio compensado para sangrar la posición de la reina para la fila actual, más un espacio adicional solo porque facilita el bucle de salida.
* *Salida Qpara la reina, seguido de una nueva línea para pasar a la siguiente fila.
* *Pruebe si r es cero, en cuyo caso hemos llegado al final del tablero y podemos salir, de lo contrario, repetiremos el ciclo principal nuevamente.

James Holderness
fuente
0

Haskell , 145 bytes

El enfoque obvio de la fuerza bruta:

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

Pruébalo en línea!

ბიმო
fuente
0

Retina , 136 bytes

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

Pruébalo en línea! Puerto de la excelente respuesta C de @ orlp. Explicación:

.+
$* 

Convierta a unario, usando espacios (hay un espacio después de *).

$_;$`Q¶

Cree Nfilas con Nespacios, a ;, luego 0..N-1espacios, luego a Q. Las etapas restantes se aplican a todas las filas.

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

Entero dividido Npor 2. (También envuelva el resultado :;para facilitar el anclaje de los patrones).

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

Si el índice del bucle es igual N/2*2, entonces deje tantos espacios.

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

Si N/2es un múltiplo de 3, tome el doble del índice de bucle más uno, módulo N/2*2+1.

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

De lo contrario, tome el doble del índice de bucle (N/2-1)más un extra 3 en la mitad inferior del tablero, módulo N/2*2.

( +)%\1?

Realmente realice la operación de módulo.

Neil
fuente
0

Carbón , 44 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Otro puerto de la excelente respuesta C de @ orlp.

Neil
fuente
0

APL (Dyalog Unicode) , SBCS de 18 bytes

Programa completo que solicita ndesde stdin. Imprime una solución separada por espacios en stdout usando ·para cuadrados vacíos y para Queens.

CY'dfns'
queens

Pruébalo en línea!

⎕CY'dfns'C op y la biblioteca "dfns"

 obtener entrada de stdin

queens encuentre todas las soluciones de Queens verdaderamente únicas (sin reflejos ni rotaciones)

 elige la primera solución

Adán
fuente
0

J , 49 bytes

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

Pruébalo en línea!

Fuerza bruta probando todas las permutaciones de longitud n .

millas
fuente