Su objetivo es implementar la operación de multiplicación XOR (sin acarreo ), definida a continuación, en la menor cantidad de bytes posible.
Si pensamos en XOR bit a bit ( ^
) como suma binaria sin llevar
101 5
^ 1001 9
----
1100 12
5^9=12
podemos realizar la multiplicación XOR @
haciendo una multiplicación larga binaria pero realizando el paso de adición sin llevar como XOR bit a bit ^
.
1110 14
@ 1101 13
-----
1110
0
1110
^ 1110
------
1000110 70
14@13=70
(Para los matemáticos, esto es multiplicación en el anillo polinomial F_2[x]
, identificando polinomios con números naturales mediante la evaluación de x=2
como un polinomio sobre Z.)
La multiplicación XOR conmuta a@b=b@a
, asocia (a@b)@c=a@(b@c)
y distribuye sobre XOR bit a bit a@(b^c)=(a@b)^(a@c)
. De hecho, es la única operación de este tipo que coincide con la multiplicación a@b=a*b
cuando sea a
y b
son poderes 2
similares 1,2,4,8...
.
Requisitos
Tome dos enteros no negativos como entrada y salida o imprima su producto XOR. Esto debería ser como números o sus representaciones de cadena decimal, no sus expansiones binarias. Pocos bytes ganan.
No se preocupe por los desbordamientos de enteros.
Aquí hay algunos casos de prueba formateados como a b a@b
.
0 1 0
1 2 2
9 0 0
6 1 6
3 3 5
2 5 10
7 9 63
13 11 127
5 17 85
14 13 70
19 1 19
63 63 1365
PCLMULQDQ
de la extensión CLMUL. Desafortunadamente, me votaron negativamente por mi conocimiento del conjunto de instrucciones x86 antes (relacionado conPEXT/PDEP
), así que voy a dejar esto como un comentario aquí.Respuestas:
código de máquina x86: 7 bytes
Solo dos instrucciones.
pclmulqdq
hace el trabajo pesado, literalmente implementa ese tipo de multiplicación xor.ret
para que sea una función invocable, ojalá satisfaga el requisito de "generar" el resultado (en el valor de retornoxmm0
). Poner argumentos enteros en argumentosxmm
es un poco inusual, pero espero que me perdones.fuente
Z80, 11 bytes
El código se llama como una función.
a
yb
están enD
yE
(el orden no importa) y la respuesta se almacenaA
cuando el código regresa (no hay funciones de E / S).Produce los resultados correctos para todas las entradas de prueba, excepto la
63@63
que se devuelve85
porque todos los registros son de 8 bits y 1365 mod 256 = 85 (desbordamiento de enteros).fuente
C,
4438 bytesGracias a nimi, ¡ahora usamos recursión por 6 bytes menos!
Definimos una función
f
que tomaa
,b
.Esto se puede llamar así:
Qué salidas:
13 @ 14 = 70
¡Pruebe los casos de prueba en línea !
fuente
f(a,b)={return(b)?(b&1)*a^f(2*a,b/2):0;}
?(b&1)
ab%2
salvar otros dos bytes ya%
tiene el mismo nivel de precedencia de izquierda a derecha a medida*
.Pyth,
1312 bytesDemostración.
Versión anterior, 13 bytes:
Demostración.
fuente
vz
tomar dos entradas enteras.CJam,
1413 bytesCómo funciona :
Primero obtenemos los resultados de la multiplicación larga y luego avanzamos desde los dos pares inferiores.
Pruébalo en línea aquí
fuente
J, 14 bytes
Uso:
Explicación (leer principalmente de derecha a izquierda;
u
yv
representar funciones arbitrarias):u&.#:
se aplicau
a los vectores de las representaciones binarias de los números de entrada y luego vuelve el resultado a un entero (u&.v == v_inverse(u(v(input_1), v(input_2)))
)*/
productos (*
) de entradas en el producto Descartes (/
) de los dos vectores binariosv(u@)
aplicaru
av
(para el producto Descartes)u/.
aplicaru
a todos los anti-diagonales del producto Descartes (los anti-diagonales representan los dígitos primero, segundo, ... en la representación binaria)~:/
reduce (/
) un anti-diagonal con operación XOR (~:
)Pruébelo en línea aquí.
fuente
Python 2, 35 bytes
Llama como
f(13, 14)
. Creo que la mayoría de los idiomas con una construcción similar convergerán en algo como esto.fuente
Java, 62
Expandido
fuente
for(;i<32;)
awhile(i<32)
? Tienen la misma longitud, pero la segunda parece una forma más natural de escribirla.i++
originalmente estaba en elfor
circuito y llegó a su posición actual. Comowhile
no es más pequeño, no hay razón para cambiarlo.Haskell, 50 bytes
Una traducción de la respuesta C de @ BrainSteel. Ejemplo de uso:
fuente
Perl - 35 bytes
Contando la opción de línea de comando como una. La entrada se toma desde un
STDIN
espacio separado.Uso de la muestra:
fuente
Julia,
353330 bytesEsto crea una función recursiva
f
que toma dos enteros y devuelve el producto XOR de las entradas.Sin golf:
¡Ahorré un par de bytes con ánimo de Sp3000!
fuente
Python 2,
104917866 bytesTome los bits
b
en orden inverso, terminando antes de presionar'0b'
al comienzo de la cadena. Multiplica cada uno pora
yxor
con el total, luego desplaza a la izquierdaa
. Luego imprima el total.fuente
Go, 63 bytes
Ejemplo completo:
http://play.golang.org/p/-ngNOnJGyM
fuente
GAP , 368 bytes
Claro, hagámoslo! (esto no se juega con precisión, lo importante era pasar a F 2 [x] y hacer los cálculos más que cualquier intento de ser una entrada ganadora)
Aquí está el código
Aquí está el código no codificado con explicación:
Bien, primero, creamos el anillo polinómico univariante sobre el campo F 2 y lo llamamos
R
. Tenga en cuenta queGF(2)
es F 2 en GAP.A continuación, vamos a asignar la variable GAP
x
a lo indeterminado del anilloR
. Ahora, cada vez que digox
en GAP, el sistema sabrá que estoy hablando de lo indeterminado del anilloR
.A continuación, tenemos dos funciones, que son mapas inversos entre sí. Estos mapas están en ambos, pero no conservan la estructura, por lo que no pude encontrar una mejor manera de implementarlos en GAP. Es casi seguro que hay una mejor manera, si lo sabes, ¡por favor comenta!
El primer mapa,
to_ring
toma un número entero y lo asigna a su elemento de anillo correspondiente. Lo hace mediante el uso de una conversión a algoritmo binario, donde cada1
que aparezca en binario se reemplaza por unx^n
dónden
es la potencia adecuada que tomaría 2 si el número fuera realmente binario.La siguiente función invierte esto.
to_ints
toma un elemento de anillo y lo asigna a su número entero correspondiente. Hago esto obteniendo una lista de los coeficientes del polinomio y para cada coeficiente distinto de cero, el resultado aumenta en 2 ^ n, de la misma manera que convertiríamos binario a decimal.Para el paso final, llamamos a estas funciones. Tomamos las dos entradas enteras, las convertimos en elementos en el anillo
R
, luego multiplicamos estos elementos y enviamos el producto a los enteros.fuente
Ruby,
767573 bytesRuby, 60 bytes (solo función, sin E / S)
fuente
Mathematica, 40 bytes
fuente
f@@{a,b,c,d}
=f[a,b,c,d]
. reference.wolfram.com/language/ref/Apply.htmlDart,
3432 bytesImplementación recursiva directa.
fuente
gnuplot, 29 bytes
al igual que en Dart (ver arriba)
fuente
Ensamblador GNU (x86_64 Mac OS X), 97 bytes
Esta es una función adecuada que se puede llamar desde C:
& puede ser probado con este programa C:
Tenga en cuenta que en Mac OS X, debe usar
clang -x c
para compilarlo como C y no como C ++.Para Linux (si no recuerdo mal), el código sería de 95 bytes:
Curiosamente, esta versión es en realidad más larga que la definición de la función en el ensamblaje en línea, pero esa era más larga que la solución C pura que ya tenemos, así que decidí probar el ensamblaje.
editar
Si se cuenta por el tamaño ensamblado (excluyendo las etiquetas, etc.), entonces es
Ensamblador x86_64, 22 bytes:
fuente
golflua 68
Básicamente realiza el mismo desplazamiento de bits que la respuesta Java de Ypnypn , pero parece requerir la división entre 2 al final para funcionar correctamente. Toma valores como stdin, ejemplos a continuación
fuente
Ceilán, 90 bytes
Este es solo el algoritmo como se describe: multiplique
a
por2^i
donde sea quei
esté instalado el bit thb
y agréguelos todos juntos usando xor. Se repite0:64
porque los enteros son de 64 bits en Ceilán cuando se ejecuta en JVM (más bajo cuando se ejecuta como Javascript, pero luegob.get(i)
solo devuelve falso).Formateado:
El alias es seguro aquí solo un byte.
fuente
(no competitiva) Jelly, 16 bytes
Pruébalo en línea!
fuente