Knight on the Rim es sombrío


48

Introducción

Aron Nimzowitsch fue un destacado maestro de ajedrez y un influyente escritor de ajedrez.

En su libro 'Mi sistema', el primer capítulo trata sobre la importancia del centro y por qué debería dominarlo. La razón simple es que tus piezas tienen más posibles movimientos directos al estar en el centro, lo que nuevamente le da más poder al jugador.

Esto se vuelve muy claro cuando se miran diferentes posiciones de un caballero y sus próximos movimientos potenciales (mostrados en rosa) en un tablero vacío:

ingrese la descripción de la imagen aquí

Objetivo

Evalúa el número de posibles próximos movimientos directos de un caballero en un tablero vacío en función de su posición.

Especificaciones de entrada

La posición del caballero.

Primero la x (columna) y luego la y (fila). 0 0Es la esquina inferior izquierda.

Para simplificar, cambié las etiquetas de un tablero de ajedrez a números solamente. Para nuestros ejemplos y casos de prueba, usamos un índice basado en 0, sin embargo, puede usar un índice basado en 1.

Puede usar cualquier tipo de formatos de entrada posibles, una matriz, argumentos de función, etc.

Especificaciones de salida

El número de posibles próximos movimientos directos para un caballero en un tablero vacío.

Casos de prueba

3 4 => 8
4 6 => 6
7 7 => 2
1 0 => 3

Los casos de prueba están empleando un índice basado en 0. La cuadrícula completa de valores es:

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

99
¡Buen primer desafío! :-)
Luis Mendo

14
"Caballero en el borde es sombrío"

2
@stacey Su comentario habría sido un gran título para este rompecabezas :)
starcorder

66
Ahora para la pregunta realmente difícil: ¿los caballeros rojos en las imágenes de arriba son todos del mismo color?
mbomb007

Respuestas:


25

Python 2 , 35 bytes

lambda x,y:50/(8+x*x/7-x+y*y/7-y)-4

Pruébalo en línea!


Python 2 , 39 bytes

lambda x,y:50/(8-x*(7-x)/5-y*(7-y)/5)-4

Pruébalo en línea!

Toma entradas indexadas en 0.

La expresión x*(7-x)/5toma los valores de coordenadas 0..7para

[0, 1, 2, 2, 2, 2, 1, 0]

( min(x,7-x,2)hace lo mismo, pero es más largo). Al sumar esto xy yda el patrón correcto pero con los números incorrectos

0 1 2 2 2 2 1 0
1 2 3 3 3 3 2 1
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
1 2 3 3 3 3 2 1
0 1 2 2 2 2 1 0

(Vea la solución de Neil para un mejor razonamiento de por qué esto da sobre el patrón correcto)

Finalmente, el mapeo a -> 50/(8-a)-4con división de piso da los valores correctos

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

Una solución alternativa igualmente larga con entradas indexadas 1:

lambda x,y:(x*(9-x)/6+y*(9-y)/6)**2/6+2

(7-a)*a/5es 3 bytes más corto que min(a,7-a,2).
Neil

1
*len realidad le cuesta un byte en general, lambda a,b:"23468"[(7-a)*a/5+(7-b)*b/5]es solo 41 bytes.
Neil

@Neil Acabo de encontrar lo mismo con x*(9-x)/6un índice.
xnor

1
¿Por qué no usas <strike>como todos los demás para mostrar el progreso del golf?
Loco

44
@Insane Creo que se ve feo y en realidad no ayuda. El código es lo importante, y cualquiera que quiera ver su evolución aún debe mirar en el historial de edición. Cuando mi antiguo código es lo suficientemente diferente como para que valga la pena mostrarlo, muestro las versiones como aquí . Pero en esta pregunta, se trata de mejoras menores en la misma estrategia, por lo que lo encontré más limpio solo por mencionar las diferentes posibilidades.
xnor

17

MATL , 17 14 13 12 bytes

¡Gracias a @Neil por 1 byte de descuento!

8:HZ^ZP5X^=s

La entrada está basada en 1.

Pruébalo en línea!

Explicación

Esto calcula la distancia euclidiana desde la entrada a cada una de las 64 posiciones en el tablero de ajedrez, y encuentra cuántos de esos valores son iguales a la raíz cuadrada de 5.

Dado que las coordenadas son valores enteros, podemos estar seguros de que los dos valores de punto flotante que representan la raíz cuadrada de 5 (que se calculan a partir de las coordenadas y que se calculan directamente) son realmente los mismos.

8:      % Push array [1 2 ... 8]
H       % Push 2
Z^      % Cartesian power. Gives 2D array [1 1; 1 2; ... 1 8; 2 1; ... 8 8]     
ZP      % Implicit input. Compute Euclidean distances, considering each row as a point
5X^     % Square root of 5
=s      % Compute how many squared distances equal sqrt(5). Implicit display

1
Impresionante y gracias por la explicación
starcorder

1
Si la comparación del cuadrado de la raíz cuadrada de 5 a 5 falla debido a errores de redondeo, ¿no puede al menos comparar la raíz cuadrada de 5 con la raíz cuadrada de 5?
Neil

@Neil ¡Gracias por la idea! Sí, dado que los cálculos son con enteros, puedo estar seguro de que las dos "raíces de 5" son el mismo doublenúmero. Hormiga salva un byte
Luis Mendo

15

Mathematica 63 43 bytes

¡Con 20 bytes guardados gracias a las sugerencias de Martin Ender!

EdgeCount[8~KnightTourGraph~8,#+1+8#2/<->_]&

Lo anterior encuentra el número de cuadrados que están a 1 salto de la celda dada en el gráfico completo del recorrido de caballeros.


g=KnightTourGraph[8,8,VertexLabels->"Name",Axes->True]

muestra el gráfico completo del recorrido del caballero, con nombres de vértices y coordenadas. Tenga en cuenta que Mathematica tiene por defecto una indexación basada en uno para las coordenadas.

grafico


#+1+8#2&[r,f]converts devuelve el vértice correspondiente al cuadrado en el rango (fila) ry el archivo (columna) f, utilizando valores basados ​​en cero como entrada.

Por ejemplo, #+1+8#2&[2,1]devuelve 11.


EdgeCount da el número de aristas en el gráfico del vecindario.


Los bordes para el rango 2, archivo 1 (cuadrado 11):

IncidenceList[8~KnightTourGraph~8, 8 #2 + # + 1] &[2, 1]

(*{1 <-> 11, 5 <-> 11, 11 <-> 17, 11 <-> 21, 11 <-> 26, 11 <-> 28}*)

Los bordes resaltados:

HighlightGraph[g, {1, 5, 11, 17, 21, 26, 28, Style[1 <-> 11, Thick, Blue], Style[5 <-> 11, Thick, Blue], Style[11 <-> 17, Thick, Blue], Style[11 <-> 21, Thick, Blue], Style[11 <-> 26, Thick, Blue], Style[11 <-> 28, Thick, Blue]},GraphHighlightStyle -> "DehighlightFade", PlotRangePadding -> .5]

realce


Método 2: distancia euclidiana

70 bytes

Este método es más largo, pero posiblemente de algún interés. El enfoque consiste en verificar la distancia euclidiana entre el centro del tablero de ajedrez y la celda de interés.

Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&

Ejemplificando

Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&@{0, 0}
Which[(x=Sqrt@Tr[({3.5, 3.5}-#)^2])<2.2,8,x<3,6,x<4,4,x<4.6,3,x>4.6,2]&@{3, 3}

2

8


Para ayudar a visualizar cómo la distancia desde el centro del tablero de ajedrez es suficiente para asignar un valor.

values={{2,3,4,4,4,4,3,2},{3,4,6,6,6,6,4,3},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{4,6,8,8,8,8,6,4},{3,4,6,6,6,6,4,3},{2,3,4,4,4,4,3,2}};
f[x_]:=Text[x,#]&/@Position[values,x]r_~w~p_:=RegionMember[{3.5`,3.5`}~Disk~r,p]
h@y_:=Which[2.2~w~y,8,3~w~y,6,4~w~y,4,4.6~w~y,3,2<3,2]

Graphics[{Circle[{4.5, 4.5}, 2.3], Circle[{4.5, 4.5}, 3], 

Círculo [{4.5, 4.5}, 4],

Círculo [{4.5, 4.5}, 4.6], Acoplar [f / @ {2, 3, 4, 6, 8}, 1]}, Ejes -> Verdadero, Ejes Origen -> {-1, -1}]


Los números 2.2, 3, 4 y 4.6 son los radios de los círculos.

imagen


1
Gran gráfico de gira
grabadora de estrellas el

20
KnightTourGraphMathematica y sus componentes ... :-)
Luis Mendo

Creo que hay un parásito #al final de su código fuente (justo antes del ]). Deberías poder usarlo en IncidenceListlugar de hacerlo EdgeList@NeighborhoodGraph. (Alternativamente, también hay EdgeCount, pero creo que eso termina siendo más largo.)
Martin Ender

1
Oh, espera, en realidad es más corto:EdgeCount[8~KnightTourGraph~8,#+1+8#2<->_]&
Martin Ender

EdgeCount¡Es genial!
DavidC

12

JavaScript (ES6), 38 bytes

(x,y)=>+"23468"[((7-x)*x+(7-y)*y)/5|0]

Toma entradas indexadas 0. Explicación: Mire los cuadrados de las distancias al centro:

24.5 18.5 14.5 12.5 12.5 14.5 18.5 24.5
18.5 12.5  8.5  6.5  6.5  8.5 12.5 18.5
14.5  8.5  4.5  2.5  2.5  4.5  8.5 14.5
12.5  6.5  2.5  0.5  0.5  2.5  6.5 12.5
12.5  6.5  2.5  0.5  0.5  2.5  6.5 12.5
14.5  8.5  4.5  2.5  2.5  4.5  8.5 14.5
18.5 12.5  8.5  6.5  6.5  8.5 12.5 18.5
24.5 18.5 14.5 12.5 12.5 14.5 18.5 24.5

El número de cuadrados alcanzables se divide en cinco bandas:

8    0-5
6    5-10
4   10-15
3   15-20
2   20-25

Realmente calculo 24.5 - (3.5 - x) ** 2 - (3.5 - y) ** 2 = (7 - x) * x + (7 - y) * y ya que es un cálculo más corto, pero todo lo que hace es revertir El orden de las bandas.


Enfoque súper conciso y muy agradable, por lo que ya no tengo que iniciar mi propia solución JS :)
starcorder

Buen punto sobre que la fórmula es equivalente sobre el radio al cuadrado. Pensé que x*(7-x)era solo una operación que se parece a un arco hacia abajo 0..7y que se ajusta a la curva, pero esto explica por qué produce un patrón tan agradable cuando se suma para xy y.
xnor

11

Jalea, 10 bytes

8ṗ2_³²S€ċ5

1 indexado. Toma un solo argumento de la forma [x,y]. Pruébalo aquí

8ṗ2          Cartesian square [[1,1],[1,2]…[8,8]]
   _³        Subtract the input
     ²S€     Compute the norm of each vector
        ċ5   Count fives

¡Dennis salvó un byte!


Solo once bytes, ¡guau!
grabadora de estrellas

Vi esta pregunta en la mañana y este es el algoritmo exacto que pensé que implementaría en Jelly cuando tuviera tiempo. : P
PurkkaKoodari

8

Mathematica, 44 40 bytes

Actualmente tengo tres soluciones en el mismo número de bytes:

2[3,4,6,8][[Tr@⌊3.2-.8Abs[#-4.5]⌋]]&
Tr@⌈.85(4-Abs[#-4.5])⌉/.{5->6,6->8}&
⌊Tr@⌈.85(4-Abs[#-4.5])⌉^1.1608⌋&

Todas esas son funciones sin nombre que toman un par de coordenadas como {3, 4}, que están basadas en 1.

Traté de encontrar una fórmula algo explícita. El patrón general en todo el tablero se ve así:

ingrese la descripción de la imagen aquí

Los valores reales de esos colores (del más claro al más oscuro) son 2, 3, 4, 6, 8. Es decir:

2 3 4 4 4 4 3 2
3 4 6 6 6 6 4 3
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
4 6 8 8 8 8 6 4
3 4 6 6 6 6 4 3
2 3 4 4 4 4 3 2

Primero explotamos la simetría desplazando el origen al centro, tomando el valor absoluto y restando el resultado 4. Esto nos da coordenadas 0.5para 3.5aumentar desde cada esquina. Para hacer que las coordenadas del centro sean las mismas, necesitamos mapear 0.5y 1.5a diferentes valores 2.5y 3.5al mismo valor. Esto se hace fácilmente multiplicando por 0.8(da {0.4, 1.2, 2., 2.8}) y colocando el resultado en el suelo. Así que ahora tenemos {0, 1, 2, 2}distancias del centro. Si sumamos las coordenadas en cada celda, obtenemos esta tabla:

0 1 2 2 2 2 1 0
1 2 3 3 3 3 2 1
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
2 3 4 4 4 4 3 2
1 2 3 3 3 3 2 1
0 1 2 2 2 2 1 0

Esto tiene valores únicos para todos los diferentes resultados posibles, por lo que simplemente lo usamos como un índice en 2[3,4,6,8].

En la segunda versión usamos techo en lugar de piso. De esta manera, 2, 3y 4ya son correctos, pero conseguimos 5y 6en lugar de6 y 8, por lo corregimos los manualmente con una regla de sustitución.

Finalmente, en la tercera versión, extendemos 5y 6hacia arriba para 6y 8por medio de exponenciación, seguido por otra operación suelo.


Me gusta mucho el enfoque que usa el patrón general del tablero, ¡genial!
grabadora de estrellas

6

APL, 21 caracteres

{+/,5=+/¨×⍨(⍳8 8)-⊂⍵}

En inglés:

  • (⍳8 8): Matriz de rango 2 de 8x8 que contiene las coordenadas de todas las celdas;
  • +/¨×⍨(⍳8 8)-⊂⍵: cuadrado de las distancias euclidianas de la celda dada con respecto a cada celda en el tablero;
  • 5=: matriz de 0/1, donde los 1 aparecen a distancias al cuadrado iguales a 5;
  • +/,: suma la matriz aplanada

Prueba (en origen 1):

    f←{+/,5=+/¨×⍨(⍳8 8)-⊂⍵}
    f¨1+(3 4)(4 6)(7 7)(1 0)
8 6 2 3

Ene sta forma:

f←{+/,5=+/¨×⍨(⍳⍺)-⊂⍵}

El argumento de la izquierda puede especificar las dimensiones del tablero. Por 8 8 flo tanto , funcionará para el tablero de ajedrez cuadrado estándar. Pero en un tablero más grande y rectangular, los casos de prueba darían resultados diferentes. Por ejemplo, en un tablero de 12x10:

    g←(10 12)∘f
    g¨1+(3 4)(4 6)(7 7)(1 0)
8 8 8 3

En la jerga de APL, una matriz es una matriz de rango 2, nada se dice sobre el contenido de las celdas. Años de (ab) uso de los términos me volvieron insensible. Actualizaré la descripción para los lectores más inclinados tradicionalmente. Gracias.
lstefano

@Istefano Ese uso de "rango" como "número de dimensiones" parece sufrir la misma aflicción :-P
Luis Mendo

Estaré ... Tienes razón! Puedes ver que ha pasado un tiempo desde que tomé Álgebra Lineal. Me
rindo

1
Programa completo, 27: ¡ ≢⍸5=+/¨×⍨-∘⎕¨⍳8 8 Pruébelo en línea!
Adám

@ Adám te refieres a 17
ngn

6

Java - 160150 bytes

int m(int r,int c){int m=0,i,j;for(i=0;i<3;i+=2)for(j=0;j<3;j+=2){m+=r+i>0&r+i<9&c+2*j>1&c+2*j<11?1:0;m+=r+2*i>1&r+2*i<11&c+j>0&c+j<9?1:0;}return m;}

Sin golf:

public static int m(int r, int c) {
    int m=0;
    for(int i=-1;i<2;i+=2)
        for(int j=-1;j<2;j+=2){
            m += r+i>-1 && r+i<8 && c+2*j>0 && c+2*j<8 ? 1:0;
            m += r+2*i>0 && r+2*i<8 && c+j>1 && c+j<8 ? 1:0;
        }
    return m;
}

El código no protegido es idéntico, excepto por cambiar los límites del bucle for para guardar 4 bytes. Funciona iterando a través de cada movimiento posible y realizando una verificación de límites (> 0 y <8). Utiliza el hecho de que los desplazamientos son (1, 2), (2, 1), (-1, 2), (-2, 1), etc. y puede verificar 2 movimientos para cada valor de i y j.

Editar: 10 bytes guardados gracias a las sugerencias de Leaky Nun y u902383.


¡Esto también fue rápido, agradable!
grabadora de estrellas

Tenía un error allí, se ha solucionado.
ejaszewski

1
int m=0,i=-1,j;guardar algunos bytes
Leaky Nun

1
cambie AND lógico a AND bit a bit y eso le permitirá eliminar 6 caracteres adicionales
user902383


5

Haskell, 49 48 bytes

w=[0..7]
x%y=sum[1|a<-w,b<-w,(a-x)^2+(b-y)^2==5]

1
Puede guardar [0..7]en una variable durante 1 byte.
xnor

5

Java, 81 caracteres (113 bytes)

int r(int a,int b){return "⍄䐲㑦晃䚈衤䚈衤䚈衤䚈衤㑦晃⍄䐲".codePointAt(a*2+b/4)>>(3-b%4)*4&15;}

Codifique toda la tabla de resultados como tabla unicode y luego obtenga los bytes apropiados realizando operaciones bit a bit

Puede verlo en línea aquí: https://ideone.com/K9BojC


3

Python, 94 bytes

lambda x,y,a=[2,1,-1,-2,-2,-1,1,2]:list((9>x+a[i]>0)&(9>y+a[5-i]>0)for i in range(8)).count(1)

Utiliza 1 indexación basada.

Demostración en https://repl.it/C6gV .





1

En realidad, 18 bytes

`;7-2km`MΣ8-:50\¬¬

Pruébalo en línea!

Esto implementa la misma fórmula que muchas otras respuestas han estado utilizando: 50/(8-x*(7-x)//5+y*(7-y))//5)-4. La entrada se toma como una lista: [x,y](o cualquier literal iterable en Python, como (x,y)o x,y).

Explicación:

`;7-2km`MΣ8-:50\¬¬
`;7-2km`M           for each value in input:
 ;7-                  make a copy, subtract from 7
    2                 push 2
     km               minimum of the three values (x, 7-x, 2)
         Σ          sum
          8-        subtract from 8
            :50\    integer divide 50 by the value
                ¬¬  subtract 2 twice

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.