Suchen Sie die Anzahl der führenden Nullen in einer 64-Bit-Ganzzahl


18

Problem:

Suchen Sie die Anzahl der führenden Nullen in einer 64-Bit-Ganzzahl mit Vorzeichen

Regeln:

  • Die Eingabe kann nicht als Zeichenfolge behandelt werden. Es kann alles sein, wo mathematische und bitweise Operationen den Algorithmus antreiben
  • Die Ausgabe sollte unabhängig von der Sprache anhand der 64-Bit-Ganzzahl mit Vorzeichen überprüft werden
  • Es gelten die Standardcode-Golfregeln
  • Kürzester Code in Bytes gewinnt

Testfälle:

Diese Tests gehen von zwei vorzeichenbehafteten Ganzzahlen aus. Wenn es Ihrer Sprache / Lösung an einer anderen Darstellung von Ganzzahlen mit Vorzeichen mangelt oder diese verwendet, rufen Sie diese bitte auf und geben Sie zusätzliche Testfälle an, die möglicherweise relevant sind. Ich habe einige Testfälle aufgenommen, die sich mit doppelter Genauigkeit befassen. Sie können jedoch auch andere vorschlagen, die aufgelistet werden sollen.

input                output   64-bit binary representation of input (2's complement)
-1                   0        1111111111111111111111111111111111111111111111111111111111111111
-9223372036854775808 0        1000000000000000000000000000000000000000000000000000000000000000
9223372036854775807  1        0111111111111111111111111111111111111111111111111111111111111111
4611686018427387903  2        0011111111111111111111111111111111111111111111111111111111111111
1224979098644774911  3        0001000011111111111111111111111111111111111111111111111111111111
9007199254740992     10       0000000000100000000000000000000000000000000000000000000000000000
4503599627370496     11       0000000000010000000000000000000000000000000000000000000000000000
4503599627370495     12       0000000000001111111111111111111111111111111111111111111111111111
2147483648           32       0000000000000000000000000000000010000000000000000000000000000000
2147483647           33       0000000000000000000000000000000001111111111111111111111111111111
2                    62       0000000000000000000000000000000000000000000000000000000000000010
1                    63       0000000000000000000000000000000000000000000000000000000000000001
0                    64       0000000000000000000000000000000000000000000000000000000000000000

13
Willkommen bei PPCG! Was ist der Grund für "die Eingabe kann nicht als Zeichenfolge behandelt werden" ? Dies disqualifiziert alle Sprachen, die keine 64-Bit-Ganzzahlen verarbeiten können, und führt wahrscheinlich nicht zu mehr Antworten, die eine Ganzzahl enthalten, da dies der einfache Weg ist, wenn sie ohnehin verfügbar sind.
Arnauld

1
Können wir zurückkehren Falsestatt 0?
Jo King

4
@Arnauld Es gibt hier und auf anderen Websites bereits ähnliche Fragen, die speziell auf Zeichenfolgen basierende Lösungen erfordern, aber nichts, was die Frage nach mathematischen und logischen Operationen aufwirft. Ich hoffe, dass es eine Reihe von unterschiedlichen Ansätzen für dieses Problem gibt, die an anderer Stelle noch nicht beantwortet wurden. Sollte dies auch für String-Lösungen offen sein, um allumfassend zu sein?
Dave

4
Einige CPUs, einschließlich x86 und ARM, haben spezielle Anweisungen dafür (x86 hat tatsächlich mehrere). Ich habe mich immer gefragt, warum Programmiersprachen diese Funktion nicht verfügbar machen, da Sie in den meisten heutigen Programmiersprachen keine Assembly-Anweisungen aufrufen können.
Slebetman

1
@ user202729 Ich glaube, ich habe dies schlecht formuliert: 'Die Ausgabe sollte unabhängig von der Sprache anhand der 64-Bit-Ganzzahldarstellung mit Vorzeichen validiert werden.' Damit meine ich, dass diese Frage die Anzahl der Nullen als Anzahl der Nullen definiert in einer 64-Bit-Ganzzahl mit Vorzeichen. Ich schätze, ich habe diese Einschränkung getroffen, um vorzeichenbehaftete und nicht vorzeichenbehaftete ganze Zahlen zu eliminieren.
Dave

Antworten:


41

x86_64-Maschinensprache unter Linux, 6 Byte

0:       f3 48 0f bd c7          lzcnt  %rdi,%rax
5:       c3                      ret

Benötigt Haswell oder K10 oder einen höheren Prozessor mit lzcntAnleitung.

Probieren Sie es online!


20
Builtins schlagen wieder zu
Logern

1
Ich empfehle, die verwendete Aufrufkonvention anzugeben (obwohl Sie es unter Linux gesagt haben)
qwr

@qwr Es sieht nach einer SysV-Aufrufkonvention aus, da der Parameter in% rdi übergeben und in% rax zurückgegeben wird.
Logern

24

Hexagony , 78 70 Bytes

2"1"\.}/{}A=<\?>(<$\*}[_(A\".{}."&.'\&=/.."!=\2'%<..(@.>._.\=\{}:"<><$

Probieren Sie es online!

Ist diese Herausforderung für eine praktische Sprache nicht zu trivial? ;)

Seitenlänge 6. Ich kann es nicht in eine Seitenlänge von 5 Sechseck passen.

Erläuterung


3
Ich habe sehr über die "Erklärung" gelacht. : D
Eric Duminil

1
Ich denke, Sie haben möglicherweise zu komplizierten Umgang mit negativen Zahlen / Null. Ich habe es geschafft, ein ähnliches Programm in die Seitenlänge 5 einzupassen, indem ich nicht diese kräftige 2 ^ 64-Berechnung durchgeführt habe. Es ist jedoch noch nicht gut golfen!
FryAmTheEggman

@fry Ah richtig, negative Zahlen haben immer 0 führende Nullen ... was definitiv zu einem kürzeren Programm führt, da die Generierung von 2 ^ 64 lang ist.
user202729

12

Python , 31 Bytes

lambda n:67-len(bin(-n))&~n>>64

Probieren Sie es online!

Das Expresson ist das bitweise &von zwei Teilen:

67-len(bin(-n)) & ~n>>64

Das 67-len(bin(-n))gibt die richtige Antwort für nicht negative Eingaben. Es nimmt die Bitlänge und subtrahiert 67, was 3 mehr als 64 ist, um das -0bPräfix zu kompensieren . Die Negation ist ein Trick, auf den man sich einstellen mussn==0 bei dem die Negation kein -Vorzeichen erzeugt.

Das & ~n>>64macht die Antwort stattdessen 0für negativ n. Wenn n<0, ~n>>64gleich 0 ist (auf 64-Bit - Integer), so und-ing mit ihm gibt 0. Wann n>=0, das ~n>>64auswertet -1und macht &-1nichts.


Python 2 , 36 Bytes

f=lambda n:n>0and~-f(n/2)or(n==0)*64

Probieren Sie es online!

Arithmetische Alternative.


9

Java 8, 32 26 Bytes.

Long::numberOfLeadingZeros

Builtins FTW.

-6 Bytes dank Kevin Cruijssen

Probieren Sie es online!


Ah, völlig vergessen numberOfLeadingZeros.. Sie können es zu 28 Bytes BTW Golf spielen:n->n.numberOfLeadingZeros(n)
Kevin Cruijssen

2
Eigentlich Long::numberOfLeadingZerosist es noch kürzer (26 Bytes).
Kevin Cruijssen

6
Wow, es kommt nicht sehr oft vor, dass Java Python schlägt. Glückwunsch!
Eric Duminil

9

C (gcc) , 14 Bytes

__builtin_clzl

Funktioniert gut auf tio

C (gcc) , 35 bis 29 Bytes

f(long n){n=n<0?0:f(n-~n)+1;}

Probieren Sie es online!

Als Dennis für 6 Bytes

C (gcc) Compiler Flags, 29 Bytes von David Foerster

-Df(n)=n?__builtin_clzl(n):64

Probieren Sie es online!


3
Bemerkenswert ist, dass es nur für 64-Bit-Computer (oder andere mit LP64 / ILP64 / etc. ABI) ist
Ruslan

1
Meine Güte, das ist sogar kürzer als jede Verwendung des integrierten GCC,__builtin_clzl mit dem ich aufwarten kann .
David Foerster

@ Ruslan: Guter Punkt, auf Systemen mit long32 Bit (einschließlich Windows x64) benötigen Sie __builtin_clzll(lange ohne Vorzeichen). godbolt.org/z/MACCKf . (Im Gegensatz zu Intel - Spezifika, GNU C builtins werden unabhängig vom Betrieb unterstützt mit einem Maschinenbefehl ist machbar Auf 32-Bit x86, clzll compiliert zu einem Zweig oder cmov zu tun. lzcnt(low half)+32Oder lzcnt(high half)Or. bsrWenn lzcntnicht verfügbar.
Peter Cordes

Die Testfälle enthalten "0", sind jedoch __builtin_clz(l)(l)undefiniertes Verhalten für Null: "Wenn x 0 ist, ist das Ergebnis undefiniert."
MCCCS

1
@MCCCS Wenn es funktioniert, zählt es. Das ist auch der Grund, warum ich die letzte Antwort
behalte

6

Perl 6 , 35 28 26 Bytes

-2 Bytes dank nwellnhof

{to .fmt("%064b")~~/^0*/:}

Probieren Sie es online!

Anonymer Codeblock, der eine Nummer entgegennimmt und eine Nummer zurückgibt. Dies konvertiert die Zahl in eine Binärzeichenfolge und zählt die führenden Nullen. Dies funktioniert für negative Zahlen, da das erste Zeichen ein -Beispiel ist -00000101und daher keine führenden Nullen vorhanden sind.

Erläuterung:

{                        }  # Anonymous code block
    .fmt("%064b")           # Format as a binary string with 64 digits
                 ~~         # Smartmatch against
                   /^0*/    # A regex counting leading zeroes
 to                     :   # Return the index of the end of the match

6

JavaScript (Node.js) , 25 Byte

Übernimmt die Eingabe als BigInt-Literal.

f=x=>x<0?0:x?f(x/2n)-1:64

Probieren Sie es online!

0


Würden Sie nicht n=>n<1?0:n.toString(2)-64dasselbe tun?
Ismael Miguel

@IsmaelMiguel Ich nehme an, du meintest n=>n<1?0:n.toString(2).length-64, aber das würde sowieso nicht funktionieren. Das würde ich denken.
Arnauld

1
@IsmaelMiguel Keine Sorge. :) Es ist in der Tat möglich, dass der .toString()Ansatz funktioniert, aber wir benötigen immer noch ein BigInt-Literal als Eingabe. Ansonsten haben wir nur 52 Bits Mantisse, was zu ungültigen Ergebnissen führt, wenn die Genauigkeit verloren geht .
Arnauld

1
Die Tatsache, dass das BigInt-Suffix dasselbe Zeichen wie Ihr Parameter ist, ist sehr verwirrend ...
Neil

1
@Neil Unlesbarer Code auf PPCG? Das kann nicht sein! Fest! : p
Arnauld





4

05AB1E , 10 9 Bytes

·bg65αsd*

I / O sind beide Ganzzahlen

Probieren Sie es online aus oder überprüfen Sie alle Testfälle .

Erläuterung:

·         # Double the (implicit) input
          #  i.e. -1 → -2
          #  i.e. 4503599627370496 → 9007199254740992
 b        # Convert it to binary
          #  i.e. -2 → "ÿ0"
          #  i.e. 9007199254740992 → 100000000000000000000000000000000000000000000000000000
  g       # Take its length
          #  i.e. "ÿ0" → 2
          #  i.e. 100000000000000000000000000000000000000000000000000000 → 54
   65α    # Take the absolute different with 65
          #  i.e. 65 and 2 → 63
          #  i.e. 65 and 54 → 11
      s   # Swap to take the (implicit) input again
       d  # Check if it's non-negative (>= 0): 0 if negative; 1 if 0 or positive
          #  i.e. -1 → 0
          #  i.e. 4503599627370496 → 1
        * # Multiply them (and output implicitly)
          #  i.e. 63 and 0 → 0
          #  i.e. 11 and 1 → 11

4

Haskell , 56 Bytes

Danke xnor, dass du einen Fehler entdeckt hast !

f n|n<0=0|1>0=sum.fst.span(>0)$mapM(pure[1,0])[1..64]!!n

Könnte ziemlich viel Speicherplatz belegen , versuche es online!

Vielleicht möchten Sie es mit einer kleineren Konstante testen: Versuchen 8-Bit!

Erläuterung

Anstatt mapM(pure[0,1])[1..64]die Eingabe in Binär umzuwandeln, verwenden wir, mapM(pure[1,0])[1..64]was im Wesentlichen die invertierten Zeichenfolgen generiert{0,1}64in lexikographischer Reihenfolge. Also können wir einfach die Summe1S-Präfix mit sum.fst.span(>0).


3

Powershell, 51 Bytes

param([long]$n)for(;$n-shl$i++-gt0){}($i,65)[!$n]-1

Testskript:

$f = {

param([long]$n)for(;$n-shl$i++-gt0){}($i,65)[!$n]-1

}

@(
    ,(-1                   ,0 )
    ,(-9223372036854775808 ,0 )
    ,(9223372036854775807  ,1 )
    ,(4611686018427387903  ,2 )
    ,(1224979098644774911  ,3 )
    ,(9007199254740992     ,10)
    ,(4503599627370496     ,11)
    ,(4503599627370495     ,12)
    ,(2147483648           ,32)
    ,(2147483647           ,33)
    ,(2                    ,62)
    ,(1                    ,63)
    ,(0                    ,64)
) | % {
    $n,$expected = $_
    $result = &$f $n
    "$($result-eq$expected): $result"
}

Ausgabe:

True: 0
True: 0
True: 1
True: 2
True: 3
True: 10
True: 11
True: 12
True: 32
True: 33
True: 62
True: 63
True: 64

3

Java 8, 38 Bytes

int f(long n){return n<0?0:f(n-~n)+1;}

Eingabe als long(64-Bit-Ganzzahl), Ausgabe als int(32-Bit-Ganzzahl).

Port von @ l4m2 's C (gcc) Antwort .

Probieren Sie es online aus.

Erläuterung:

 int f(long n){       // Recursive method with long parameter and integer return-type
   return n<0?        //  If the input is negative:
           0          //   Return 0
          :           //  Else:
           f(n-~n)    //   Do a recursive call with n+n+1
                  +1  //   And add 1

BEARBEITEN: Kann 26 Bytes lang sein, Long::numberOfLeadingZeroswenn die in @ lukegs Java 8-Antwort angezeigte integrierte Funktion verwendet wird .


3

APL + WIN, 34 Bytes

+/×\0=(0>n),(63⍴2)⊤((2*63)××n)+n←⎕

Erläuterung:

n←⎕ Prompts for input of number as integer

((2*63)××n) If n is negative add 2 to power 63

(63⍴2)⊤ Convert to 63 bit binary

(0>n), Concatinate 1 to front of binary vector if n negative, 0 if positive

+/×\0= Identify zeros, isolate first contiguous group and sum if first element is zero


3

Gelee ,  10  9 Bytes

-1 dank eines tollen Tricks von Erik dem Outgolfer (ist jetzt einfach nicht negativ )

ḤBL65_×AƑ

Ein monadischer Link, der eine ganze Zahl (innerhalb des Bereichs) akzeptiert, die eine ganze Zahl ergibt.

Probieren Sie es online! Oder sehen Sie sich die Testsuite an .


Die 10 war ḤBL65_ɓ>-×

Hier ist eine weitere 10-Byte-Lösung, die mir gefällt, da sie "BOSS" heißt ...

BoṠS»-~%65

Test-Suite hier

... BoṠS63r0¤i, BoṠS63ŻṚ¤ioder BoṠS64ḶṚ¤iwürde auch funktionieren.


Weitere 10 Bytes (von Dennis) sind æ»64ḶṚ¤Äċ0(wieder æ»63r0¤Äċ0und æ»63ŻṚ¤Äċ0werden auch funktionieren)



@EriktheOutgolfer Ich dachte mir "es muss einen golferischen Weg geben, um mit isNonNegative zu multiplizieren" und dachte überhaupt nicht an die Ƒschnelle, sehr schöne Arbeit!
Jonathan Allan

1
Eigentlich theoretisiere ich schon seit einiger Zeit. Seien Sie gewarnt, dass es nicht vektorisiert! ;-) Eigentlich heißt es "Abflachen und dann prüfen, ob alle Elemente nicht negativ sind".
Erik the Outgolfer

2

Perl 5 , 37 Bytes

sub{sprintf("%064b",@_)=~/^0*/;$+[0]}

Probieren Sie es online!

Oder diese 46 Bytes, wenn die "Stringifizierung" nicht erlaubt ist: sub z

sub{my$i=0;$_[0]>>64-$_?last:$i++for 1..64;$i}

s/length$&/$+[0]/(-3 Bytes);)
Dada

IMO, Sie dürfen das subSchlüsselwort nicht aus Antworten entfernen, die Perl 5-Funktionen enthalten.
Nwellnhof

Ich habe gesehen, was dem Entfernen subin Antworten für andere Sprachen, Perl6, Powershell und mehr ähnelt.
Kjetil S.

In Perl6 müssen Sie meines Erachtens kein sub{}(anonymes?) Sub erstellen, was erklärt, warum es in Perl6-Antworten weggelassen wurde. Ich bin mit @nwellnhof einverstanden, dass Sie nicht entfernen dürfen sub. (als ich noch aktiv war, wie vor einem Jahr oder so, das war die Regel)
Dada

jetzt geändert. Und enthalten $+[0].
Kjetil S.

2

Swift (auf einer 64-Bit-Plattform), 41 Byte

Deklariert einen aufgerufenen Closure, fder ein akzeptiert und zurückgibt Int. Diese Lösung funktioniert nur richtig 64-Bit - Plattformen, wo Intsich typealiasauf ed Int64. ( Int64Kann auf einer 32-Bit-Plattform explizit für den Parametertyp des Closures verwendet werden, wobei 2 Byte hinzugefügt werden.)

let f:(Int)->Int={$0.leadingZeroBitCount}

In Swift ist sogar der ganzzahlige Grundtyp ein gewöhnliches Objekt, das in der Standardbibliothek deklariert ist. Dies bedeutet, Intdass Methoden und Eigenschaften vorhanden sein können, z. B. leadingZeroBitCount(dies ist für alle Typen erforderlich, die dem FixedWidthIntegerProtokoll der Standardbibliothek entsprechen ).


interessant. erinnert mich an Rust. Ich denke, es sollte als 20 Bytes zählen, .LeadingZeroBitCount
Don Bright

2

Haskell , 24 Bytes

f n|n<0=0
f n=1+f(2*n+1)

Probieren Sie es online!

Dies ist im Grunde die gleiche wie die Java-Lösung von Kevin Cruijssen, aber ich habe sie unabhängig gefunden.

Das Argument sollte einen Typ Intfür einen 64-Bit-Build oder Int64für irgendetwas haben.

Erläuterung

Wenn das Argument negativ ist, ist das Ergebnis sofort 0. Andernfalls verschieben wir uns mit Einsen nach links , bis wir eine negative Zahl erreichen. Mit dieser Füllung vermeiden wir einen Sonderfall für 0.

Nur als Referenz, hier ist der offensichtliche / effiziente Weg:

34 Bytes

import Data.Bits
countLeadingZeros



1

Perl 5 -p , 42 Bytes

1while$_>0&&2**++$a-1<$_;$_=0|$_>=0&&64-$a

Probieren Sie es online!

Länger als eine Bitstring-basierte Lösung, aber eine anständige Mathe-basierte Lösung.


Funktioniert nicht wirklich, wenn ich mich nicht irre
Dada

@Dada Ich sehe, dass es einige Fälle gibt, in denen die Gleitkommadivision nicht richtig funktioniert. Ich habe einen intAnruf getätigt, der das Problem lösen sollte.
Xcali

Es tut mir leid, ich habe meine Kopie nicht bestanden, wie es scheint. Dies ist, was ich senden wollte;)
Dada

1

APL (NARS), 15 Zeichen, 30 Byte

{¯1+1⍳⍨⍵⊤⍨64⍴2}

Teste für ein paar Zahlen, um zu sehen, wie man es benutzt:

  f←{¯1+1⍳⍨⍵⊤⍨64⍴2}
  f ¯9223372036854775808
0
  f 9223372036854775807
1


1

K (ngn / k) , 6 Bytes

64-#2\

Probieren Sie es online!

2\ codiere das Argument in binär

# Länge

64- subtrahieren von 64


# = length... sieht stringbasiert aus
Titus

2
@Titus 2\ gibt eine Liste von Ganzzahlen an und ermittelt #deren Länge. Hier sind keine Zeichenfolgen beteiligt.
13.

1

PHP, 50 46 Bytes

for(;0<$n=&$argn;$n>>=1)$i++;echo$n<0?0:64-$i;

Laufen Sie als Pipe mit -Roder versuchen Sie es online ,

<?=$argn<0?0:0|64-log($argn+1,2);hat Rundungsprobleme; Also habe ich den langen Weg genommen.


1

Wolfram Language (Mathematica) , 41 Bytes

Die Formel für positive Zahlen ist gerecht 63-Floor@Log2@#& . Ersetzungsregeln werden für die Sonderfälle Null und negative Eingabe verwendet.

Die Eingabe muss keine 64-Bit-Ganzzahl mit Vorzeichen sein. Dadurch wird das Wort der Eingabe effektiv in eine Ganzzahl umgewandelt. Wenn Sie eine Zahl außerhalb der normalen Grenzen für eine 64-Bit-Ganzzahl eingeben, wird eine negative Zahl zurückgegeben, die angibt, wie viele weitere Bits zum Speichern dieser Ganzzahl erforderlich wären.

63-Floor@Log2[#/.{_?(#<0&):>2^63,0:>.5}]&

Probieren Sie es online!

@ LegionMammal978s Lösung ist mit 28 Bytes ziemlich viel kürzer. Die Eingabe muss eine Ganzzahl sein. Pro der Dokumentation: „ BitLength[n]ist effektiv eine effiziente Version Floor[Log[2,n]]+1.“ Es sorgt automatisch für den Fall von Null Berichterstattung korrekt 0statt -∞.

Wolfram Language (Mathematica) , 28 Byte

Boole[#>=0](64-BitLength@#)&

Probieren Sie es online!


1
Boole[#>=0](64-BitLength@#)&ist mit 28 Bytes etwas kürzer. Es verwendet das gleiche Grundkonzept wie Ihr, gilt aber BitLengthund Boole.
LegionMammal978

Ich habe BitLength total vergessen!
Kelly Lowder

1

bitNumber - math.ceil (math.log (number) / math.log (2))

zB 64-Bit-NUMMER: 9223372036854775807 math.ceil (math.log (9223372036854775807) / math.log (2)) ANS: 63


Wenn Sie den Namen der Sprache hinzufügen könnten, wäre das großartig, da die Leute wahrscheinlich Antworten, bei denen der Name der Sprache nicht enthalten ist,
ablehnen würden
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.