J'essaie d'utiliser C # pour trouver l'index du premier 1 (de droite à gauche) dans la représentation binaire d'un nombre. Par exemple, puisque 100 en binaire est:
0b1100100
Le premier 1 est en troisième position à partir de la droite, il devrait donc donner 3.
234 devrait donner 2, 0 devrait donner 0, etc.
Voici ma solution actuelle:
k < 1 ? 0 :(int)Math.Log(k & -k, 2) + 1;
Est-ce que je peux raccourcir cela?
Convert.ToString(k,2).IndexOf("1")
est ce que vous voulez, ou quelque chose de similaire, un mauvais site.Réponses:
Si seulement les intrinsèques spécifiques à la machine pris en charge par C # ... Il existe une seule instruction qui peut le faire dans le langage d'assemblage x86, ainsi que sur la plupart des autres architectures de processeur. Vous auriez alors non seulement le code le plus court, mais probablement le plus rapide.
En fait, raccourcir ce code est un problème extrêmement ennuyeux par rapport à rendre ce code rapide . Il existe toutes sortes de solutions très soignées, efficaces et qui tournent les bits, et vous pouvez également envisager d'utiliser une table de recherche.
Rien de tout cela n'a d'importance pour le golf, cependant. Il me semble que votre solution actuelle est la meilleure que vous puissiez faire. Bien sûr, vous pouvez supprimer les espaces blancs superflus:
Je l'écrirais personnellement comme:
parce que je pense que c'est un peu plus clair d'avoir la direction du test conditionnel de cette façon, ainsi que de le comparer à zéro, mais je suppose que c'est six dans un sens, une demi-douzaine dans l'autre.
C # ne supporte pas la conversion implicite de
int
labool
comme C et C ++ font, vous ne pouvez pas réduire vraiment le test conditionnel plus loin.Vous êtes également bloqué avec la distribution explicite de
double
(comme retourné monMath.Log
) àint
, car C # ne permettra pas que cela se produise implicitement. Bien sûr, c'est normalement une bonne chose car cela soulignerait que vous avez un gros problème de performances ici: promouvoir unint
en undouble
, calculer le journal d'undouble
, puis reconvertir ledouble
résultat en unint
sera extrêmement lent, donc c'est normalement quelque chose que vous voudriez éviter. Mais ce sont les types de perversions que vous devez supporter lorsque vous jouez au golf à code.J'avais initialement trouvé
(non golfé pour plus de clarté, bien sûr), ce qui évite de prendre le logarithme et est donc une amélioration de la taille et de la vitesse du code. Malheureusement, cela n'obtient pas toujours la bonne réponse, et je suppose que c'est une exigence inflexible. :-) Plus précisément, il échoue si la valeur d'entrée (
k
) est un facteur de 8. Ceci est réparable, mais pas sans allonger le code que laMath.Log
version.la source
Math
doit être entièrement qualifié, donc votre autre version devrait être meilleure même si je n'ai pas réellement compté les octets.System.
il doit être plus court et correct.