Contexte
Si vous jouez beaucoup au code, vous êtes probablement au courant de l' opération XOR au niveau du bit . Étant donné deux entiers, il donne un autre entier avec 1
s dans les bits où les deux entrées diffèrent. Ainsi, par exemple 1010 XOR 0011 = 1001
,.
Il s'avère très utile dans la théorie des jeux, où il est mieux connu sous le nom de «nim sum». Si vous avez la somme de deux jeux (c'est-à-dire que vous effectuez des mouvements dans un jeu à la fois), la valeur de la position est la somme nim des valeurs des positions dans chaque jeu individuel.
Mais nous pouvons aller plus loin. Avec l'addition nim et une définition appropriée de la multiplication nim , nous pouvons former un champ à partir des entiers non négatifs. Le défi consiste donc à multiplier les nim au golf.
Définition
La multiplication Nim obéit aux règles suivantes:
Le produit nim d'un Fermat 2-puissance n = (2 ^ (2 ^ k)) avec un nombre plus petit est le produit ordinaire.
Le produit nim d'un n de Fermat 2-power est lui-même 3n / 2.
La multiplication Nim distribue sur l'addition nim.
La multiplication Nim est commutative et associative (tout comme l'addition nim).
L'identité multiplicative est 1 (et l'identité additive est 0).
Tout entier non négatif peut être écrit comme la somme nim de puissances distinctes de deux, et toute puissance de deux peut être écrite comme le produit de nombres Fermat distincts, donc cela suffit pour définir la multiplication nim pour tous les entiers non négatifs.
Exemple
Tout cela était assez abstrait, alors travaillons à travers un exemple. Je vais utiliser +
pour désigner l'addition nim (XOR) et *
pour la multiplication 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
Cas de test supplémentaires
4, 4 -> 6
4, 3 -> 12
4, 7 -> 10
2, 4 -> 8
2, 3 -> 1
1, 42 -> 42
Défi
Écrivez un programme ou une fonction qui, étant donné deux entiers non négatifs sous n'importe quelle forme pratique, calcule leur produit nim.
C'est du golf de code , donc la soumission la plus courte l'emporte.
Réponses:
Nim , 120 octets
Essayez-le en ligne!
OK, cela peut être fou, mais quelqu'un a dû faire une multiplication Nim dans Nim ...
Il s'agit d'un algorithme standard de Wikipedia. Le problème est que je ne connais pas la langue, donc j'ai dû apprendre les bases à la volée. En particulier, cela m'a surpris
-=
etmin
n'a pas fonctionné pour les ensembles, et le meilleur moyen que j'ai réussi à trouver pour extraire le minimum était d'utiliser l'itérateur et de renvoyer la première valeur. Espérons que les experts Nim m'aideront à améliorer cela.la source
Python 2 , 85 octets
Essayez-le en ligne!
Lent comme diable. Calcule mex ({α ′ β ⊕ α β ′ ⊕ α 'β ′: α ′ <α, β ′ <β}) récursivement.
la source
Gelée , 16 octets
Utilise la formule récursive xy = mex ({ay ⊕ xb ⊕ ab: a <x, b <y}) pour la multiplication du nombre .
Essayez-le en ligne!
Comment ça fonctionne
la source
CGSuite ,
523922 octetsJe ne savais pas qu'il avait cette "procédure" intégrée et anonyme.
Version originale, 36 octets:
Ou 25 octets si l'entrée / sortie peut être des nombres:
Eh bien, j'espérais
*a**b
/a*b
travailler, mais ça ne marche pas.la source
Pyth , 21 octets
Manifestation
Utilise la formulation d'élément exclu minimum de multiplication nim, comme indiqué ici .
Deux cartes imbriquées sont utilisées pour itérer sur toutes les valeurs plus petites (
mm ... GH
), puis les résultats sont aplatis (s
). La partie intelligente est livrée avecf-T ... 0
, où nous parcourons les entiers vers le haut à partir de 0 pour trouver le premier non contenu dans l'ensemble mentionné ci-dessus. En procédant de cette façon, nous n'avons pas besoin de calculer une limite supérieure d'itération, économisant quelques octets.Au final, la fonction
g
calcule le produit nim.la source
JavaScript (ES6),
142128 octetsLa première étape consiste à diviser les deux
x
ety
en un XOR de pouvoirs de2
, prendre leurs produits nim par paire, puis XOR les résultats (car le produit nim se distribue sur XOR). Une fois que nous sommes revenus au cas dex
et auxy
deux puissances de 2, nous notons que les puissances de Fermat se multiplient entre elles en utilisant l'arithmétique ordinaire, nous pouvons donc factoriserx
ety
en puissances de Fermat. Six
ety
ne partagent pas une puissance Fermat , nous pouvons inverser le processus et revenir simplementx * y
. Cependant, s'ils partagent une puissance de Fermat, alors nous divisons les deuxx
ety
par cette puissance, calculons le produit nim, puis prenons le produit nim avec le carré nim de cette puissance de Fermat. Non golfé:la source
Wolfram Language (Mathematica) , 81 octets
Essayez-le en ligne!
En utilisant la formule:
la source