El juego
Nim es un juego de estrategia matemática, donde 2 jugadores se turnan para tomar elementos de montones distintos. En su turno, debe tomar al menos un artículo, y puede tomar tantos como desee, siempre que solo tome de un montón. ¡El jugador que tome el último elemento gana! Este es un juego resuelto. Antes de entrar en la estrategia, puedes intentar jugarla en línea aquí .
La estrategia
La estrategia ganadora se explica muy claramente y simplemente aquí en este enlace. Lo explicaré con un poco más de términos técnicos. La forma de ganar este juego es tomar siempre tantos elementos como sea posible para que la suma digital binaria sea siempre 0. Considere el siguiente tablero:
*
* *
* * *
* * * *
* * * * *
1 2 3 4 5
Para encontrar la suma binaria-digital de esta placa, debe:
Convierta el número en cada fila a binario. Entonces tenemos 001, 010, 011, 100 y 101.
Sume todos los números juntos e ignore cualquier carga.
001 010 011 100 +101 ---- 001
También puede hacer bit-xor cada número, y esto logrará el mismo resultado.
Ahora, si la suma en esta configuración actual es 001, entonces esto no es (todavía) una tabla ganadora. ¡Pero puedes convertirlo en una tabla ganadora! Si quitamos un elemento de las columnas 1, 3 o 5, la suma será 0. Este es un tablero ganador, lo que significa que, siempre que no se equivoque, el siguiente jugador en moverse perderá. Así que siempre debes terminar tu turno con una tabla ganadora. Digamos que quitas un elemento de la columna 5. Ahora el tablero se ve así:
* *
* * *
* * * *
* * * * *
1 2 3 4 5
Mientras no lo arruines, tienes una victoria garantizada. No hay nada que tu oponente pueda hacer para detenerte. Digamos que toma todos los elementos de la columna 5.
*
* *
* * *
* * * *
1 2 3 4 5
¿A dónde irías después? No se desplace hacia abajo todavía e intente resolverlo usted mismo.
En este momento, la suma es 100. El mejor movimiento (y el único movimiento ganador) sería tomar todo de la columna 4. Eso dejaría el tablero así:
*
* *
* * *
1 2 3 4 5
y la suma como esta
001
010
+011
----
000
eso significa que estás en una tabla ganadora! ¡Hurra!
El reto
Debe escribir un programa o función que, dado un tablero de nim, devolverá un movimiento ganador o un valor falsey si no hay un movimiento ganador.
Tu aportación:
Será el formato de la lista nativa de su idioma, donde cada elemento de la lista corresponde al número de elementos en una columna determinada. Por ejemplo, la entrada {4, 2, 1, 0, 3} corresponde a la siguiente placa nim:
* * * * * * * * * * 1, 2, 3, 4, 5
(opcional) El número de filas. (Para lenguajes como C / C ++ donde esto no se conoce de la lista misma).
Su salida:
Puede ir a STDOUT o ser devuelto desde la función
Deben ser dos números, 1) la columna de la que estamos eliminando (recuerde que las columnas están indexadas en 0) y 2) el número de elementos que se eliminarán de esa fila. Esto podría ser una matriz de 2 elementos, una cadena de los dos números, etc. Tenga en cuenta que la respuesta puede tener más de 2 dígitos, por lo que devolver la cadena "111" no es válida porque no está claro si esto significa "Eliminar un elemento de la columna once" o "Eliminar once elementos de la columna uno". "1,11" u "11,1" serían aceptables.
Si no hay respuesta, devuelva o imprima un valor falso. Si su idioma solo puede devolver un tipo de variable (de nuevo, como C / C ++), un número negativo para la columna, o 0 o menos para el número a eliminar serían valores de falsey aceptables.
Si el número de columna o el número a eliminar son demasiado grandes, esto se considera una salida no válida.
Entradas / salidas de muestra
[1, 2, 3, 4, 5]
---> [0, 1]
o [4, 1]
o[2, 1]
[1, 3, 5, 6]
---> [0, 1]
o [1, 1]
o[2, 1]
[1, 2, 0, 0, 5]
---> [4, 2]
[1, 2, 3]
---> ERROR
Si elige hacer una función en lugar de un programa completo, debe escribir un programa completo para demostrar la función en acción. Esto no contará para su puntaje completo. Además, se espera que los programas se ejecuten en un período de tiempo razonable. No planeo ingresar entradas excesivamente grandes, por lo tanto, siempre que su programa no esté haciendo una búsqueda de fuerza bruta en todo el árbol del juego, debería estar bien.
Como de costumbre, este es el código de golf, por lo que se aplican agujeros de bucle estándar , y las respuestas se cuentan en bytes.
Tabla de clasificación
Aquí hay un fragmento de pila para generar una tabla de clasificación regular y una descripción general de los ganadores por idioma.
Para asegurarse de que su respuesta se muestre, comience con un título, usando la siguiente plantilla de Markdown:
# Language Name, N bytes
¿Dónde N
está el tamaño de su envío? Si mejora su puntaje, puede mantener los puntajes antiguos en el título, tachándolos. Por ejemplo:
# Ruby, <s>104</s> <s>101</s> 96 bytes