Votre objectif est d’implémenter l’opération de multiplication XOR ( carryless ), définie ci-dessous, avec le moins d’octets possible.
Si nous pensons que XOR ( ^
) au niveau des bits est une addition binaire sans porter
101 5
^ 1001 9
----
1100 12
5^9=12
nous pouvons effectuer la multiplication XOR @
en effectuant une multiplication binaire longue mais en effectuant l'étape d'ajout sans effectuer de traitement XOR au niveau du bit ^
.
1110 14
@ 1101 13
-----
1110
0
1110
^ 1110
------
1000110 70
14@13=70
(Pour les mathématiciens, il s'agit d'une multiplication dans l'anneau polynomial F_2[x]
, identifiant des polynômes avec des nombres naturels en évaluant at x=2
comme polynôme sur Z.)
La multiplication XOR commute a@b=b@a
, associe (a@b)@c=a@(b@c)
et distribue sur XOR au niveau du bit a@(b^c)=(a@b)^(a@c)
. En fait, c’est l’unique opération de ce type qui correspond à la multiplication à tout a@b=a*b
moment a
et qui b
sont des pouvoirs 2
similaires 1,2,4,8...
.
Exigences
Prenez deux entiers non négatifs en entrée et en sortie ou imprimez leur produit XOR. Cela devrait être sous forme de nombres ou leurs représentations en chaîne décimale, pas leurs développements binaires. Le moins d'octets gagne.
Ne vous inquiétez pas des débordements d'entiers.
Voici quelques cas de test au format 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 l'extension CLMUL. Malheureusement, ma connaissance du jeu d'instructions x86 a déjà été votéePEXT/PDEP
, je vais donc laisser cela comme un commentaire.Réponses:
Code machine x86: 7 octets
Seulement deux instructions.
pclmulqdq
fait le gros du travail, il met littéralement en œuvre ce type de multiplication xor.ret
pour en faire une fonction appelable, satisfaisant, nous l'espérons, l'exigence de "sortie" du résultat (dans la valeur de retour,xmm0
). Mettre des arguments entiers dansxmm
args est un peu inhabituel, mais j'espère que vous me pardonnerez.la source
Z80, 11 octets
Le code est appelé en tant que fonction.
a
etb
sont dansD
etE
(l'ordre n'a pas d'importance) et la réponse est stockéeA
lorsque le code est retourné (il n'y a pas de fonctions d'E / S).Il produit les résultats corrects pour toutes les entrées de test, à l'exception de celles
63@63
renvoyées,85
car tous les registres sont à 8 bits et 1365 mod 256 = 85 (débordement d'entier).la source
C,
4438 octetsGrâce à nimi, nous utilisons maintenant la récursion pour 6 octets de moins!
On définit une fonction
f
qui prenda
,b
.Cela peut s'appeler comme:
Quelles sorties:
13 @ 14 = 70
Essayez les cas de test en ligne !
la source
f(a,b)={return(b)?(b&1)*a^f(2*a,b/2):0;}
?(b&1)
parb%2
deux autres octets, car%
le même niveau de priorité de gauche à droite est identique à celui de*
.Pyth,
13 à12 octetsManifestation.
Ancienne version, 13 octets:
Manifestation.
la source
vz
de prendre deux entrées entières.CJam,
14 à13 octetsComment ça marche :
Nous obtenons d’abord les résultats de multiplication longs, puis progressons à partir des deux paires inférieures.
Essayez-le en ligne ici
la source
J, 14 octets
Usage:
Explication (lisant principalement de droite à gauche;
u
etv
représenter des fonctions arbitraires):u&.#:
s'appliqueu
aux vecteurs des représentations binaires des nombres en entrée puis retourne le résultat à un entier (u&.v == v_inverse(u(v(input_1), v(input_2)))
)*/
produits (*
) d'entrées dans le produit Descartes (/
) des deux vecteurs binairesv(u@)
appliqueru
àv
(au produit Descartes)u/.
s'appliqueu
à chaque anti-diagonale du produit Descartes (les anti-diagonales représentent les 1er, 2ème, ... chiffres de la représentation binaire)~:/
réduire (/
) un anti-diagonal avec opération XOR (~:
)Essayez-le en ligne ici.
la source
Python 2, 35 octets
Appelle comme
f(13, 14)
. Je pense que la plupart des langues avec une construction similaire vont converger vers quelque chose comme ça.la source
Java, 62
Étendu
la source
for(;i<32;)
àwhile(i<32)
? Ils ont la même longueur, mais la seconde semble être une façon plus naturelle de l'écrire.i++
c'était à l'origine de lafor
boucle et que le golf a atteint sa position actuelle. Puisque cewhile
n'est pas plus petit, il n'y a aucune raison de le changer.Haskell, 50 octets
Une traduction de la réponse C de @ BrainSteel. Exemple d'utilisation:
la source
Perl - 35 octets
Compter l'option de ligne de commande comme un. L'entrée est prise à partir d'
STDIN
espaces séparés.Exemple d'utilisation:
la source
Julia,
353330 octetsCela crée une fonction récursive
f
qui prend deux entiers et retourne le produit XOR des entrées.Ungolfed:
Enregistré quelques octets avec les encouragements de Sp3000!
la source
Python 2,
104917866 octetsPrenez les bits
b
dans l'ordre inverse, en terminant avant de frapper'0b'
au début de la chaîne. Multipliez chaque para
etxor
avec le total, puis tournez à gauchea
. Puis imprimez le total.la source
Go, 63 octets
Exemple complet:
http://play.golang.org/p/-ngNOnJGyM
la source
GAP , 368 octets
Bien sûr, faisons ça! (Ce n'est que vaguement joué au golf, le but était plutôt de passer à F 2 [x] et de faire les calculs plus que toute tentative d'être une entrée gagnante)
Voici le code
Voici le code non-golfé avec explication:
D'abord, nous créons l'anneau polynomial univarié sur le corps F 2 et l'appelons
R
. Notez queGF(2)
c'est F 2 dans GAP.Ensuite, nous allons affecter la variable GAP
x
à l'indéterminé de l'anneauR
. Maintenant, chaque fois que je disx
dans GAP, le système saura que je parle de l'indétermination de la bagueR
.Ensuite, nous avons deux fonctions, qui sont des cartes inverses l’une de l’autre. Ces cartes sont sur les deux, mais elles ne préservent pas la structure, donc je ne pouvais pas trouver un meilleur moyen de les implémenter dans GAP. Il y a presque certainement une meilleure solution. Si vous le savez, veuillez commenter!
La première carte,
to_ring
prend un entier et le mappe à l'élément anneau correspondant. Pour ce faire, il utilise un algorithme de conversion en binaire, où tout1
ce qui apparaît en binaire est remplacé par unx^n
oùn
est la puissance appropriée que 2 prendrait si le nombre était effectivement binaire.La fonction suivante inverse cela.
to_ints
prend un élément en anneau et le mappe sur son entier correspondant. Je le fais en obtenant une liste des coefficients du polynôme et, pour chaque coefficient non nul, le résultat est augmenté de 2 ^ n, de la même manière que nous convertirions les valeurs binaires en valeurs décimales.Pour la dernière étape, nous appelons ces fonctions. Nous prenons les deux entrées entières, les convertissons en éléments dans l'anneau
R
, puis multiplions ces éléments ensemble et renvoyons le produit aux entiers.la source
Ruby,
767573 octetsRuby, 60 octets (fonction uniquement, pas d'E / S)
la source
Mathematica, 40 octets
la source
f@@{a,b,c,d}
=f[a,b,c,d]
. reference.wolfram.com/language/ref/Apply.htmlDart,
3432 octetsImplémentation récursive simple.
la source
gnuplot, 29 octets
comme dans Dart (voir ci-dessus)
la source
Assembleur GNU (x86_64 Mac OS X), 97 octets
C'est une fonction appropriée qui peut être appelée à partir de C:
& peut être testé avec ce programme C:
Notez que sur Mac OS X, vous devez l’utiliser
clang -x c
pour le compiler en tant que C & non C ++.Pour Linux (si je me souviens bien), le code serait de 95 octets:
Curieusement, cette version est en réalité plus longue que la définition de la fonction dans l'assemblage en ligne, mais celle-ci était plus longue que la solution en C pure que nous avons déjà, alors j'ai décidé d'essayer l'assemblage.
modifier
S'il est compté par la taille assemblée (à l'exclusion des étiquettes, etc.), alors c'est
Assembleur x86_64, 22 octets:
la source
golflua 68
Fait fondamentalement le même changement de bits que la réponse Java de Ypnypn , mais semble exiger que la division par 2 à la fin fonctionne correctement. Prend des valeurs en tant que stdin, exemples ci-dessous
la source
Ceylan, 90 octets
C'est juste l'algorithme tel que décrit: multipliez
a
par2^i
où que lei
th soit placéb
, et additionnez-les tous en utilisant xor. Itère0:64
parce que les entiers sont à 64 bits dans Ceylan lorsqu'ils sont exécutés sur la machine virtuelle Java (inférieur lors de l'exécution en tant que Javascript, maisb.get(i)
ne renvoie ensuite que la valeur false).Formaté:
L'alias coffres ici juste un seul octet.
la source
(non-concurrent) Jelly, 16 octets
Essayez-le en ligne!
la source