Ich versuche, mit C # den Index der ersten 1 (von rechts nach links) in der binären Darstellung einer Zahl zu finden. Zum Beispiel, da 100 in binär ist:
0b1100100
Die erste 1 befindet sich an dritter Stelle von rechts, sollte also 3 ergeben.
234 sollte 2 ergeben, 0 sollte 0 ergeben usw.
Hier ist meine aktuelle Lösung:
k < 1 ? 0 :(int)Math.Log(k & -k, 2) + 1;
Wie kann ich das kürzer machen?
Convert.ToString(k,2).IndexOf("1")
ist das, was Sie wollen, oder eine ähnliche, falsche Seite.Antworten:
Wenn nur C # maschinenspezifische Eigenschaften unterstützt… Es gibt eine einzige Anweisung, die dies in der x86-Assemblersprache und auf den meisten anderen Prozessorarchitekturen tun kann. Dann hätten Sie nicht nur den kürzesten Code, sondern höchstwahrscheinlich auch den schnellsten.
In der Tat ist es ein äußerst langweiliges Problem , diesen Code kürzer zu machen, als diesen Code schnell zu machen . Es gibt alle möglichen wirklich netten, effizienten und unkomplizierten Lösungen, und Sie können auch eine Nachschlagetabelle verwenden.
Nichts davon ist jedoch für das Golfen von Bedeutung. Mir scheint, Ihre aktuelle Lösung ist die beste, die Sie tun können. Natürlich können Sie das überflüssige Leerzeichen entfernen:
Ich würde es persönlich schreiben als:
weil ich denke, dass es etwas klarer ist, die Richtung des bedingten Tests auf diese Weise zu haben und sie mit Null zu vergleichen, aber ich denke, es ist sechs in eine Richtung, ein halbes Dutzend in die andere.
C # unterstützt keine implizite Konvertierung von
int
nachbool
C und C ++, sodass Sie den bedingten Test nicht weiter verkürzen können.Sie bleiben auch bei der expliziten Besetzung von
double
(wie von my zurückgegebenMath.Log
) bisint
, da C # dies nicht implizit zulässt. Natürlich ist das normalerweise eine gute Sache, denn es würde darauf hinweisen, dass Sie hier ein großes Leistungsproblem haben: Das Heraufstufen von aint
zu adouble
, das Berechnen des Protokolls von adouble
und das anschließende Konvertieren desdouble
Ergebnisses in aint
wird massiv langsam sein, also ist es normalerweise etwas das würdest du vermeiden wollen. Aber das sind die Arten von Perversionen, mit denen Sie sich beim Code-Golf abfinden müssen.Ich hatte mir anfangs ausgedacht
(aus Gründen der Übersichtlichkeit natürlich ungolfed), wodurch der Logarithmus vermieden wird und daher die Codegröße und -geschwindigkeit verbessert wird. Leider erhält dies nicht immer die richtige Antwort, und ich gehe davon aus, dass dies eine unflexible Anforderung ist. :-) Insbesondere schlägt es fehl, wenn der Eingabewert (
k
) ein Faktor von 8 ist. Dies kann behoben werden, jedoch nicht ohne den Code länger als dieMath.Log
Version zu machen.quelle
Math
voll qualifiziert sein muss, damit Ihre andere Version besser sein sollte, obwohl ich die Bytes nicht wirklich gezählt habe.System.
, sollte er kürzer und korrekt sein.