C # Erste 1 (von rechts nach links) in Binärzahl


10

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?


1
Der offensichtliche Tipp ist, Ihre überflüssigen Leerzeichen zu entfernen. Ich sehe 10 Leerzeichen, die Sie leicht entfernen können.
James

Convert.ToString(k,2).IndexOf("1")ist das, was Sie wollen, oder eine ähnliche, falsche Seite.
Magic Octopus Urn

14
@ Close-Voter - Warum die Close-Votes? Ich denke, dies ist eine Frage zu Tipps zum Thema . Oder gab es Regeländerungen, die ich in dieser Hinsicht verpasst habe?
Digitales Trauma

Antworten:


3

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:

k<1?0:(int)Math.Log(k&-k,2)+1

Ich würde es persönlich schreiben als:

k>0?(int)Math.Log(k&-k,2)+1:0

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 intnach boolC 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ückgegeben Math.Log) bis int, 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 a intzu a double, das Berechnen des Protokolls von a doubleund das anschließende Konvertieren des doubleErgebnisses in a intwird 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

k > 0
      ? ((k & -k) >> 1) + 1
      : 0

(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 die Math.LogVersion zu machen.


Beachten Sie, dass für Code Golf das Mathvoll qualifiziert sein muss, damit Ihre andere Version besser sein sollte, obwohl ich die Bytes nicht wirklich gezählt habe.
TheLethalCoder

Du meinst den, der die falsche Ausgabe erzeugt? @the
Cody Gray

Nun, Sie sagten, es gibt eine Lösung, aber es würde es länger machen. Wenn der Fix kürzer ist als in der OPs-Version System., sollte er kürzer und korrekt sein.
TheLethalCoder
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.