Les anciens Grecs avaient ces choses appelées des nombres simples et doublement pairs. Par exemple, un nombre pair est 14. Il peut être divisé par 2 une fois et est devenu un nombre impair (7) après lequel il n'est plus divisible par 2. Un nombre doublement pair est 20. Il peut être divisé par 2, puis devient 5.
Votre tâche consiste à écrire une fonction ou un programme prenant un nombre entier en entrée et indiquant le nombre de fois qu'il est divisible par 2 sous forme de nombre entier, avec le moins d'octets possible. L'entrée sera un entier différent de zéro (toute valeur positive ou négative, dans les limites de votre langue).
Cas de test:
14 -> 1
20 -> 2
94208 -> 12
7 -> 0
-4 -> 2
La réponse avec le moins d'octets gagne.
Conseil: Essayez de convertir le nombre en base 2. Voyez ce que cela vous dit.
The input will be a nonzero integer
Est-ce que cela doit être édité suite à votre commentaire sur le fait que zéro soit une entrée potentielle?Réponses:
Gelée , 4 octets
Dans la dernière version de Jelly,
ÆEḢ
(3 octets) fonctionne.Essayez ici .
la source
x86_64 code machine, 4 octets
L'instruction BSF (bit scan forward) fait exactement cela !
En assembleur de style gcc, ceci est:
L'entrée est donnée dans le registre de l' EDI et renvoyé dans le registre EAX selon la norme 64 bits c conventions d' appel.
En raison de l’encodage binaire à complément à deux, cela fonctionne pour les nombres aussi bien que les +.
En outre, malgré la documentation qui dit "Si le contenu de l'opérande source est 0, le contenu de l'opérande de destination est indéfini". , Je trouve sur ma machine virtuelle Ubuntu que la sortie
f(0)
est 0.Instructions:
evenness.s
et assembler avecgcc -c evenness.s -o evenness.o
evenness-main.c
et compilez avecgcc -c evenness-main.c -o evenness-main.o
:Ensuite:
gcc evenness-main.o evenness.o -o evenness
./evenness
@FarazMasroor a demandé plus de détails sur la manière dont cette réponse a été obtenue.
C étant plus familier avec les subtilités de l’assemblage x86, j’utilise généralement un compilateur pour générer le code d’assemblage. Je sais par expérience que les extensions gcc telles que
__builtin_ffs()
,__builtin_ctz()
et__builtin_popcount()
généralement compiler et assembler 1 ou 2 instructions sur x86. J'ai donc commencé avec une fonction c comme:Au lieu d’utiliser une compilation gcc normale jusqu’au code objet, vous pouvez utiliser l’
-S
option de compilation juste pour assembler -gcc -S -c evenness.c
. Cela donne un fichier d'assemblageevenness.s
comme ceci:Beaucoup de cela peut être joué au golf. En particulier, nous savons que la convention d'appel c pour les fonctions avec signature est simple et agréable: le paramètre d'entrée est passé dans le registre et la valeur de retour est renvoyée dans le registre. Nous pouvons donc extraire la plupart des instructions - beaucoup d’entre elles concernent la sauvegarde des registres et la configuration d’un nouveau cadre de pile. Nous n'utilisons pas la pile ici, mais uniquement le registre, vous n'avez donc pas à vous soucier des autres registres. Cela laisse le code de montage "golfé":
int f(int n);
EDI
EAX
EAX
Notez que @zwol fait remarquer que vous pouvez également utiliser une compilation optimisée pour obtenir un résultat similaire. En particulier,
-Os
produit exactement les instructions ci-dessus (avec quelques directives d'assembleur supplémentaires qui ne produisent pas de code objet supplémentaire).Ceci est maintenant assemblé avec
gcc -c evenness.s -o evenness.o
, qui peut ensuite être lié à un programme de pilote de test comme décrit ci-dessus.Il existe plusieurs façons de déterminer le code machine correspondant à cet assemblage. Mon préféré est d'utiliser la
disass
commande de désassemblage de gdb :Nous pouvons donc voir que le code machine pour l'
bsf
instruction est0f bc c7
et pourret
estc3
.la source
evenness-main.c
avec différents paramètres d'optimisation; pour moi , il rompt avec-O
,-O2
ou-O3
.Python, 25 octets
n & -n
met à zéro tout sauf le bit le moins significatif, par exemple ceci:Nous sommes intéressés par le nombre de zéros à la fin, nous le convertissons donc en une chaîne binaire en utilisant
bin
, ce qui sera pour le nombre ci-dessus"0b10000"
. Puisque nous ne nous soucions pas de la0b
, ni de la1
, nous soustrayons 3 de la longueur de cette chaîne.la source
Pyth, 6 octets
Essayez ici .
la source
JavaScript (ES6), 18 octets
4 octets plus court que
31-Math.clz32
. Hah.la source
Math.clz32
...JavaScript ES6,
2219 octetsOn dirait que la récurrence est le chemin le plus court.
la source
Pyth, 8 octets
Par exemple, la représentation binaire de
94208
est:Après division sur
1
s et prise du dernier élément du tableau résultant, ceci devient:C'est 12 zéros, donc c'est "même 12".
Cela fonctionne parce qu’il
x / 2
s’agit essentiellement,x >> 1
c’est-à-dire d’un changement de bit à droite1
. Par conséquent, un nombre n'est divisible par 2 que lorsque le LSB l'est0
(comme un nombre décimal est divisible par 10 lorsque son dernier chiffre est0
).la source
05AB1E ,
4 à5 octetsPrend maintenant en charge les nombres négatifs. Code:
Essayez-le en ligne!
Explication:
Utilise le codage CP-1252.
la source
Pyth, 6 octets
Fondamentalement juste
la source
MATL , 5 octets
Cela fonctionne pour tous les entiers.
Essayez-le en ligne!
la source
C, 36 (28) octets
(Ne pas tester l'argument zéro car un argument différent de zéro a été spécifié.)
Mise à jour (en réponse au commentaire) : Si nous autorisons les déclarations de fonction de style K & R, nous pouvons avoir une version de 28 octets:
Dans ce cas, nous nous basons sur le fait que le compilateur utilise par défaut les deux
n
et le type de retourf
toint
. Ce formulaire génère cependant un avertissement avec C99 et ne compile pas en tant que code C ++ valide.la source
int n
-> len
code C est toujours valide et élimine 4 caractères.Java 7, 39 ou peut-être 44 octets
Yay récursion! Je devais utiliser un
!=
comparaison au lieu d'une comparaison plus courte pour ne pas déborder sur les entrées négatives, mais à part cela, c'est assez simple. Si c'est étrange, envoyez un zéro. Si même, ajoutez-en un et recommencez.Il existe deux versions car, pour le moment, la sortie pour zéro est inconnue. Le premier recurse jusqu'à ce que la pile déborde et ne génère rien car 0 est infiniment pair. La seconde crache un joli 0, sûr, mais probablement non rigoureux mathématiquement, pour la sortie.
la source
JavaScript (ES6),
20 octets19 octets.Ceci est un portage de la solution Haskell de @nimi to JavaScript. Il utilise les propriétés "court-circuit"
&&
dont renvoie son côté gauche s'il s'agit de falsey (ce qui est dans ce cas-0
) ou son autre côté. Pour mettre en œuvre,odd x = 0
nous faisons donc le côté gauche1 - (x % 2)
qui bouillonne à0
travers le&&
, sinon nous retournons à1 + f(x / 2)
.Le rasage de
1 - (x % 2)
as(~x) % 2
est dû à @Neil ci-dessous et présente la propriété étrange qui permet à la fonction ci-dessus d'être émise-0
pour de petits nombres impairs. Cette valeur est une particularité de la décision de JS selon laquelle les entiers sont des doubles IEEE754; ce système a un séparé+0
et-0
qui sont spécialement conçus en JavaScript pour être l'un===
pour l'autre. L'~
opérateur calcule l'inversion binaire sur le nombre entier signé de 32 bits pour le nombre, qui pour les petits nombres impairs sera un nombre pair négatif. (Le nombre positifMath.pow(2, 31) + 1
par exemple produit0
plutôt que-0
.) La restriction étrange aux nombres entiers signés 32 bits n'a aucun autre effet; en particulier cela n'affecte pas la correction.la source
~x&1
est un octet plus court que1-x%2
.Perl 6,
2318 octetsusage
la source
Ruby 24 octets
Ma première soumission de golf de code (yey!)
Comment je suis arrivé ici :
Tout d'abord, je souhaitais obtenir un code conforme aux spécifications afin de comprendre le problème. J'ai donc construit la méthode sans tenir compte du nombre d'octets:
Fort de cette connaissance, j'ai décompressé la fonction dans une boucle while et ajouté
$*
(ARGV) comme entrée et i comme nombre de fois que le nombre a été divisé par deux avant de devenir impair.J'étais assez fier de cela et je l'avais presque soumis avant de me rendre compte que toute cette division par deux me semblait un peu binaire, étant un ingénieur en logiciel mais pas tellement un informaticien, ce n'était pas la première chose à laquelle on a pensé.
J'ai donc rassemblé quelques résultats sur les valeurs d'entrée en binaire:
J'ai remarqué que le résultat était le nombre de positions à gauche que nous devons parcourir avant que le nombre ne devienne impair.
En faisant quelques manipulations simples de chaîne, j'ai divisé la chaîne à la dernière occurrence de 1 et compté la longueur des 0 restants:
en utilisant le
("%b" % x)
formatage pour convertir un nombre en binaire, et String # slice pour trancher ma chaîne.J'ai appris quelques choses sur le rubis au cours de cette quête et j'ai hâte de voir d'autres golfs bientôt!
la source
@wizzwizz4
au début d'un commentaire pour me répondre. (Cela fonctionne avec tous les noms d'utilisateur!)J, 6 octets
Explication:
la source
C, 37 octets
f(int x){return x?x&1?0:1+f(x/2):0;}
Vérifiez récursivement le dernier bit jusqu'à ce que ce ne soit pas un 0.la source
f(int n){return __builtin_ctz(n);}
si vous êtes prêt à utiliser les extensions gcc. Ou même#define f __builtin_ctz
int
. C'est implicite, tout comme le type de retour.f(n){...}
? GCC ne le compilera pas. Je ne suis pas un expert en C, mais une recherche rapide révèle que cette fonctionnalité a peut-être été supprimée dans les versions plus récentes de C. Elle sera donc peut-être compilée avec les indicateurs appropriés.-ansi
- être ou-gnu99
? Je sais que je l'ai obtenu au travail. J'ai écrit une réponse de conseils à ce sujet!Haskell, 28 octets
Exemple d'utilisation:
f 94208
->12
.Si le nombre est impair, le résultat est
0
, sinon,1
plus un appel récursif avec la moitié du nombre.la source
div x 2
? Pourquoi ne pasx/2
?div
est une division entière, une division en/
virgule flottante.Befunge, 20
L’exécution du code continue de se déplacer vers la droite et d’enrouler autour du deuxième caractère de la première ligne (grâce au tirant arrière
#
) jusqu’à la2%
sortie1
, ce qui entraîne_
le changement de direction vers la gauche, puis|
vers le haut, qui encercle<
la deuxième ligne, qui sorties et sorties. Nous incrémentons chaque élément de la pile à travers la boucle, puis divisons le sommet par 2.la source
Rétine ,
2917Essayez-le en ligne!
2 octets sauvés grâce à Martin!
Prend une entrée unaire. Cela correspond de manière répétée à la plus grande quantité de
1
s possible, de sorte que le nombre de1
s corresponde exactement au reste des1
s du nombre. Chaque fois qu'il le fait, il ajoute un a;
à la chaîne. À la fin, nous comptons le nombre de;
s dans la chaîne.Si vous voulez une entrée décimale, ajoutez:
au début du programme.
la source
Jolf, 6 octets
Essayez-le ici!
Plutôt simple ... Félicitations à ETHProductions pour avoir évincé Jolf de la version qui devrait vraiment fonctionner!
la source
PARI / GP, 17 octets
la source
6502 langage machine, 7 octets
Pour trouver la valeur de position du bit le moins significatif 1 de la valeur non nulle dans l'accumulateur, en laissant le résultat dans le registre X:
Pour exécuter ceci sur le simulateur 6502 sur e-tradition.net , préfixez -le
A9
suivi d'un entier de 8 bits.Cela se désassemble comme suit:
Ceci est équivalent au C suivant, sauf que C requiert
int
avoir au moins 16 bits:La même chose fonctionne sur un 65816, en supposant que MX = 01 (accumulateur 16 bits, index 8 bits), et est équivalente à l’extrait C ci-dessus.
la source
Brachylog ,
2715 octetsExplication
la source
CJam, 8 octets
Lire un entier, une valeur absolue, factoriser en premier, compter deux.
la source
JavaScript ES6, 36
38octetsGolfé deux octets grâce à @ETHproductions
Réponse assez ennuyeuse, mais ça fait le travail. Peut-être en réalité trop semblable à une autre réponse, s’il ajoute les modifications suggérées, je supprimerai les miennes.
Pour l'exécuter, attribuez-le à une variable (
a=>{for...
) car il s'agit d'une fonction anonyme, puis appelez-le aveca(100)
.la source
b%2==0
peut être changé enb%2-1
etc++
peut être déplacé dans la dernière partie de lafor
déclaration. Je pense que cela fonctionnerait aussi:b=>eval("for(c=0;b%2-1;b/=2)++c")
b%2-1
=>~b&1
Je pense aussi que cela échoue lors de la saisie de0
, ce qui peut être corrigé avecb&&~b&1
b%2-1
la vérification échoue pour les nombres impairs négatifs.ES6, 22 octets
Retourne -1 si vous passez 0.
la source
DUP , 20 octets
Try it here!
Converti en récursion, la sortie est maintenant le premier chiffre de la pile. Usage:
Explication
la source
Japt,
9 à5 octetsTestez-le en ligne!
La version précédente aurait dû être cinq octets, mais celle-ci fonctionne réellement.
Comment ça fonctionne
la source
C,
444038 36 octets2 octets off merci @JohnWHSmith . 2 octets off merci @luserdroog .
Testez en direct sur ideone .
la source
!(n%2)
par un joli petit~n&1
.=0
. Les globales sont implicitement initialisées à 0.a
, n'est-elle pas garantie de fonctionner uniquement lors de son premier appel? Je ne savais pas que c'était autorisé.