Antecedentes
Si hace mucho golf de código, es probable que conozca la operación XOR bit a bit . Dados dos enteros, da otro entero con 1
s en los bits donde las dos entradas difieren. Entonces, por ejemplo 1010 XOR 0011 = 1001
,.
Resulta ser muy útil en la teoría de juegos, donde se conoce mejor como la "suma nim". Si tiene la suma de dos juegos (es decir, está haciendo movimientos en un juego a la vez), el valor de la posición es la suma mínima de los valores de las posiciones en cada juego individual.
Pero podemos llevar esto un paso más allá. Con la suma de nim y una definición apropiada de multiplicación de nim , podemos formar un campo a partir de los enteros no negativos. Entonces, el desafío es la multiplicación de nim de golf.
Definición
La multiplicación de Nim obedece las siguientes reglas:
El producto nim de un Fermat 2-power n = (2 ^ (2 ^ k)) con cualquier número menor es el producto ordinario.
El producto nim de un Fermat 2-power n consigo mismo es 3n / 2.
La multiplicación de nim se distribuye sobre la suma de nim.
La multiplicación de nim es conmutativa y asociativa (como lo es la adición de nim).
La identidad multiplicativa es 1 (y la identidad aditiva es 0).
Cualquier número entero no negativo se puede escribir como la suma nim de potencias distintas de dos, y cualquier potencia de dos se puede escribir como el producto de números Fermat distintos, por lo que esto es suficiente para definir la multiplicación nim para todos los números enteros no negativos.
Ejemplo
Todo fue bastante abstracto, así que analicemos un ejemplo. Usaré +
para denotar la suma de nim (XOR) y *
para la multiplicación de nim.
6 * 13
= (4 + 2) * (8 + 4 + 1)
= (4 + 2) * ((4 * 2) + 4 + 1)
= (4 * 4 * 2) + (4 * 2 * 2) + (4 * 4) + (4 * 2) + (4 * 1) + (2 * 1)
= (6 * 2) + (4 * 3) + 6 + 8 + 4 + 2
= ((4 + 2) * 2) + 12 + 6 + 8 + 4 + 2
= (4 * 2) + (2 * 2) + 12 + 6 + 8 + 4 + 2
= 8 + 3 + 12 + 6 + 8 + 4 + 2
= 15
Casos de prueba adicionales
4, 4 -> 6
4, 3 -> 12
4, 7 -> 10
2, 4 -> 8
2, 3 -> 1
1, 42 -> 42
Desafío
Escriba un programa o función que, dados dos enteros no negativos en cualquier forma conveniente, calcule su producto nim.
Este es el código de golf , por lo que gana la presentación más corta.
Respuestas:
Nim , 120 bytes
Pruébalo en línea!
OK, esto puede ser una locura, pero alguien tuvo que hacer la multiplicación de Nim en Nim ...
Este es un algoritmo estándar de Wikipedia. El problema es que no sé el idioma, así que tuve que aprender los conceptos básicos sobre la marcha. En particular, me sorprendió eso
-=
ymin
no funcionó para conjuntos, y la mejor manera que pude encontrar para extraer el mínimo fue usar el iterador y devolver el primer valor. Con suerte, los expertos de Nim me ayudarán a mejorar esto.fuente
Python 2 , 85 bytes
Pruébalo en línea!
Lento como diablos. Calcula mex ({α ′ β ⊕ α β ′ ⊕ α 'β ′: α ′ <α, β ′ <β}) de forma recursiva.
fuente
Jalea , 16 bytes
Utiliza la fórmula recursiva xy = mex ({ay ⊕ xb ⊕ ab: a <x, b <y}) para la multiplicación de nimber .
Pruébalo en línea!
Cómo funciona
fuente
CGSuite ,
523922 bytesNo me di cuenta que tiene este "procedimiento" incorporado y anónimo.
Versión original, 36 bytes:
O 25 bytes si la entrada / salida podría ser nimbers:
Bueno, esperaba
*a**b
/a*b
trabajar, pero no es así.fuente
Pyth , 21 bytes
Demostración
Utiliza la formulación mínima de elementos excluidos de la multiplicación de nim, como se indica aquí .
Se utilizan dos mapas anidados para iterar sobre todos los valores más pequeños (
mm ... GH
), luego los resultados se aplanan (s
). La parte inteligente viene conf-T ... 0
, donde iteramos sobre enteros hacia arriba desde 0 para encontrar el primero que no figura en el conjunto mencionado anteriormente. Al hacerlo de esta manera, no necesitamos calcular un límite superior de iteración, ahorrando unos pocos bytes.Al final, la función
g
calcula el producto nim.fuente
JavaScript (ES6),
142128bytesEl primer paso es dividir ambos
x
yy
en un XOR de poderes de2
, tomar sus productos nim por pares y luego XOR los resultados (porque el producto nim se distribuye sobre XOR). Una vez que hemos recursed al caso dex
yy
ambas potencias de 2, observamos que los poderes de Fermat se multiplican entre sí utilizando la aritmética ordinaria, por lo que puede, por tanto, factorizarx
yy
en potencias de Fermat. Six
yy
no compartimos un poder de Fermat, podemos revertir el proceso y simplemente regresarx * y
. Sin embargo, si comparten un poder de Fermat, entonces dividimos ambosx
yy
por ese poder, calculamos el producto nim, luego tomamos el producto nim con el cuadrado nim de ese poder de Fermat. Sin golf:fuente
Wolfram Language (Mathematica) , 81 bytes
Pruébalo en línea!
Usando la fórmula:
fuente