Berechnen Sie die längste Folge von Einsen im Binärwert einer ganzen Zahl


32

Tor

Erstellen Sie bei einer nicht negativen Ganzzahl eine Funktion, die die Startposition der Anzahl der größten aufeinanderfolgenden Einsen im Binärwert dieser Ganzzahl zurückgibt.

Wenn Sie eine Eingabe erhalten 0, kehren Sie zurück 0.

Wenn die Zahl mehrere gleich lange Streifen aufweist, müssen Sie die Position des letzten Streifens zurückgeben.

Eingang

Eine ganze Zahl größer oder gleich 0.

Ausgabe

Eine Ganzzahl, die wie unten erläutert berechnet wird.

Regeln

  • Das ist Code-Golf, also gewinnt der kürzeste Code in Bytes in jeder Sprache.
  • Standardlücken sind verboten.

Beispiele und Testfälle

Beispiel 1

  • Ihrer Funktion wird die Ganzzahl 142 übergeben
  • 142 entspricht 10001110 im Binärformat
  • Die längste Serie ist "111" (eine Serie von drei)
  • Der Streifen beginnt an der Position 2 ^ 1
  • Ihre Funktion gibt als Ergebnis 1 zurück

Beispiel 2

  • Ihrer Funktion wird die Ganzzahl 48 übergeben
  • 48 entspricht 110000 in binär
  • Die längste Serie ist "11" (eine Serie von zwei)
  • Der Streifen beginnt an der Position 2 ^ 4
  • Ihre Funktion gibt als Ergebnis 4 zurück

Beispiel 3

  • Ihrer Funktion wird die Ganzzahl 750 übergeben
  • 750 entspricht 1011101110 im Binärformat
  • Die längste Serie ist "111" (eine Serie von drei)
  • Da es zwei gleich lange Streifen gibt, geben wir den späteren Streifen zurück.
  • Die spätere Serie beginnt an der Position 2 ^ 5
  • Ihre Funktion gibt als Ergebnis 5 zurück

1
Sie benötigen ein
Gewinnkriterium

@Okx Es wurde im Text selbst erwähnt, also habe ich den Tag hinzugefügt.
Totalhuman

Stellen Sie sicher, dass die Leute testen 0. Das ist ein wichtiger Testfall.
mbomb007

2
Anstelle von "letzter Streifen" oder "letzter Streifen" würde ich "Streifen mit dem größten Platzwert" vorschlagen.
Aschepler

@Okx Warum ist ein Gewinnkriterium notwendig? Warum kann es nicht einfach ein Puzzle sein?
CorsiKa

Antworten:


21

Gelee , 10 8 Bytes

Ba\ÐƤṀċ¬

Probieren Sie es online!

Wie es funktioniert

Ba\ÐƤṀċ¬  Main link. Argument: n


B         Binary; convert n to base 2.

   ÐƤ     Apply the link to the left to all postfixes of the binary array.
 a\         Cumulatively reduce by logical AND.

          For example, the array

          [1, 0, 1, 1, 1, 0, 1, 1, 1, 0]

          becomes the following array of arrays.

          [1, 0, 0, 0, 0, 0, 0, 0, 0, 0]
             [0, 0, 0, 0, 0, 0, 0, 0, 0]
                [1, 1, 1, 0, 0, 0, 0, 0]
                   [1, 1, 0, 0, 0, 0, 0]
                      [1, 0, 0, 0, 0, 0]
                         [0, 0, 0, 0, 0]
                            [1, 1, 1, 0]
                               [1, 1, 0]
                                  [1, 0]
                                     [0]

     Ṁ    Take the lexicographical maximum, i.e., the array with the most 1's at
          the beginning, breaking ties by length.

       ¬  Yield the logical NOT of n, i.e., 0 if n > 0 and 1 if n = 0.

      ċ   Count the occurrences of the result to the right in the one to the left.

Herzliche Glückwünsche!
Defacto

24

JavaScript (ES6), 41 40 36 34 Byte

4 Bytes dank @ThePirateBay gespart

f=x=>(k=x&x/2)?f(k):Math.log2(x)|0

Testfälle

Wie?

Allgemeiner Fall x> 0

Wir UNDEN rekursiv die Eingabe x mit x / 2 , wodurch die Muster der aufeinanderfolgenden gesetzten Bits progressiv reduziert werden, bis nur das am weitesten rechts stehende Bit der Sequenz übrig bleibt. Wir behalten eine Kopie des letzten Nicht-Null-Werts und bestimmen die Position seines höchstwertigen Bits durch Rundung seines Logarithmus zur Basis 2.

Nachfolgend sind die Schritte aufgeführt, die wir für x = 750 ausführen ( 1011101110 im Binärformat) ausführen .

    1011101110 --.
,----------------'
'-> 1011101110
AND 0101110111
    ----------
=   0001100110 --.
,----------------'
'-> 0001100110
AND 0000110011
    ----------
=   0000100010 --.  --> output = position of MSB = 5  (0000100010)
,----------------'                                         ^
'-> 0000100010
AND 0000010001
    ----------
=   0000000000

Kantenfall x = 0

Der Sonderfall x = 0führt sofort zu Math.log2(0) | 0. Der Logarithmus von 0auswertet zu-Infinity und das binäre bitweise ODER erzwingt einen Zwang auf eine 32-Bit-Ganzzahl. In Übereinstimmung mit der Spezifikation der abstrakten Operation ToInt32 ergibt dies das erwartete 0:

Wenn Zahl ist NaN , +0 , -0 , + ∞ oder -∞ , Rückkehr +0


Diese Fehler für die Eingabe 0, die Teil des Eingabebereichs ist.
Justin Mariner

@JustinMariner Behoben.
Arnauld

Was ist mit Math.log2(k)|0statt 31-Math.clz32(k)? Oder vermisse ich etwas?

@ThePirateBay Math.log2(k)|0ist eigentlich sowohl kürzer als auch einfacher für den Sonderfall x=0. Vielen Dank. :)
Arnauld

1
Sehr schöner Algorithmus und gute Erklärung. Ich habe es in 14 Byte x86-Maschinencode implementiert .
Peter Cordes

12

x86-Maschinencode, 14 Byte

Mit @ Arnaulds Algorithmus von x &= x>>1und die höchsten Satz Bit - Position in dem Schritt nimmt vorx wird 0.

Aufrufbar von C / C ++ mit Signatur unsigned longest_set(unsigned edi);im x86-64 System V ABI. Dieselben Maschinencode-Bytes werden im 32-Bit-Modus auf dieselbe Weise dekodiert, aber die Standard-32-Bit-Aufrufkonventionen setzen nicht das erste Argument ein edi. (Das Ändern des Eingaberegisters auf ecxoder edxfür Windows _fastcall/ _vectorcalloder gcc -mregparmkann durchgeführt werden, ohne etwas zu beschädigen.)

   address   machine-code
             bytes
                         global longest_set
 1                       longest_set:
 2 00000000 31C0             xor  eax, eax    ; 0 for input = 0
 3                       
 4                       .loop:               ; do{
 5 00000002 0FBDC7           bsr  eax, edi    ;  eax = position of highest set bit
 6                           ;; bsr leaves output unmodified when input = 0 (and sets ZF)
 7                           ;; AMD documents this; Intel manuals say unspecified but Intel CPUs implement it
 8 00000005 89F9             mov  ecx, edi
 9 00000007 D1E9             shr  ecx, 1
10 00000009 21CF             and  edi, ecx
11 0000000B 75F5             jnz .loop        ; } while (x &= x>>1);
12                       
13 0000000D C3               ret

Die BSRAnweisung von x86 (Bit Scan Reverse) ist dafür perfekt. Sie gibt uns den Bit-Index direkt, anstatt führende Nullen zu zählen. ( Erzeugt bsrnicht direkt 0 für Eingabe = 0 wie 32-lzcnt(x)würde, aber wir brauchen bsr = 31-lzcnt für Nicht-Null-Eingaben, alsolzcnt würden nicht einmal Anweisungen speichern, geschweige denn Byte zählen. Nullen von eax, bevor die Schleife funktioniert wegen bsr' s semi-offizielles Verhalten, das Ziel unverändert zu lassen, wenn die Eingabe Null ist.)

Dies wäre sogar noch kürzer, wenn wir die MSB-Position am längsten zurückgeben könnten. In diesem Fall würde lea ecx, [rdi+rdi](3 Bytes) + Linksverschiebung anstelle von kopierenmov +shr (4 Bytes) .

Siehe diesen TIO-Link für einen ASM-Anrufer, der dies tutexit(longest_set(argc-1));

Testen mit einer Shell-Schleife:

l=(); for ((i=0;i<1025;i++));do 
    ./longest-set-bitrun "${l[@]}";   # number of args = $i
    printf "$i %#x: $?\n" $i; 
    l+=($i); 
done | m

0 0: 0
1 0x1: 0
2 0x2: 1
3 0x3: 0
4 0x4: 2
5 0x5: 2
6 0x6: 1
7 0x7: 0
8 0x8: 3
9 0x9: 3
10 0xa: 3
11 0xb: 0
12 0xc: 2
13 0xd: 2
14 0xe: 1
15 0xf: 0
16 0x10: 4
17 0x11: 4
18 0x12: 4
19 0x13: 0
20 0x14: 4
21 0x15: 4

...

747 0x2eb: 5
748 0x2ec: 5
749 0x2ed: 5
750 0x2ee: 5
751 0x2ef: 0
752 0x2f0: 4
753 0x2f1: 4
754 0x2f2: 4

1
Nett! Ein Hinweis für diejenigen, die (wie ich) mit anderen Assembly-Dialekten vertraut sind: Die x86-BSR-Mnemonik steht für "Bit Scan Reverse", nicht für "Branch to SubRoutine".
Arnauld

@Arnauld: guter Punkt, bearbeitet, um die Mnemonik zu dekodieren und einen Link zum Eintrag im Referenzhandbuch zu haben.
Peter Cordes

5

Jelly , 19 17 11 Bytes

HÐĿ&\ḟ0ṪBL’

Probieren Sie es online!

-6 (!) Bytes dank @ Dennis's scharfen Beobachtungen

Wie es funktioniert

HÐĿ&\ḟ0ṪBL’
HÐĿ         - halve repeatedly until reaching 0 due to rounding
   &\       - cumulative AND
     ḟ0Ṫ    - final non-zero, or 0 if all elements are 0
        BL  - length of binary representation (log base 2). 0->[0]->1
          ’ - decrement

Fehler für 0, die im Eingabebereich liegen.
Mr. Xcoder

@ Mr.Xcoder Behoben
fireflame241

Sie können ein Byte für das Update mitȯ-µ...
Jonathan Allan

@ JonathanAllan Ich verstehe nicht, wie OR-Ing helfen würde. Hast du Code?
Fireflame241

1
Da Bimmer ein Array zurückgegeben wird, das mit einer 1 beginnt , BUṪMṪ’×Ṡkann es werden ṪBL’. Außerdem brauchen Sie das nicht und ḟ0sparen ein Byte mehr ¹Ðf.
Dennis

5

Python 2 , 45 Bytes

f=lambda x:f(x&x/2)if x&x/2else len(bin(x))-3

Probieren Sie es online!

Dank Dennis viele Bytes gespart! (Die Köpfe nach oben len(bin(...))-3statt math.frexp)

Vielen Dank an @xnor für das Auffinden eines Fehlers, der zum Glück leicht zu beheben war!


Dies scheint falsche Antworten zu geben, wie zum Beispiel für x=3, ich denke, weil die and/orKurzschlüsse falsch sind, wenn die Funktion 0 zurückgibt.
xnor

@xnor Danke, dass du das bemerkt hast! Es ist repariert.
Mr. Xcoder

4

Perl 6 ,45 35 Bytes

Diese stark verbesserte Version wurde freundlicherweise von @nwellnhof zur Verfügung gestellt.

{.msb+1-(.base(2)~~m:g/1+/).max.to}

Probieren Sie es online!


Sie können einfach mit übereinstimmen :g, um alle Übereinstimmungen zu erhalten. Mit dem Smart-Match-Operator konnte ich bis zu 40 Bytes Golf spielen:{sort(.base(2).flip~~m:g/1+/).tail.from}
nwellnhof


@nwellnhof, vielen Dank. Ich habe das irgendwie verpasst :gund nicht herausgefunden, wie ich Adverb mit dem Smartmatch-Operator verwenden kann. Auch die .msbMethode ist hier sehr hilfreich und ich wusste es vorher nicht.
Ramillies

3

Python 2 , 89 78 Bytes

m=t=i=j=0
for c in bin(input()):
 t=-~t*(c>'0');i+=1
 if t>m:j=i;m=t
print i-j

Probieren Sie es online!

BEARBEITEN: 11 Bytes dank Mr. Xcoder gespeichert.




@ Mr.Xcoder Daran habe ich auch gedacht, obwohl in der Frage ausdrücklich gefragt wird, eine Funktion zu schreiben.
Jonathan Frech

@ JonathanFrech Ich glaube nicht, dass das OP wirklich Funktion bedeutete . Wahrscheinlich nur ein Oberbegriff.
Mr. Xcoder

@ Mr.Xcoder Bitte erläutern Sie dies. Vielen Dank,
Lifebalance

3

05AB1E , 14 12 11 Bytes

bDγàŠrkrJgα

Probieren Sie es online! oder Testfälle ausführen .

Erläuterung

bDγàŠrkrJgα  Implicit input (ex: 750)
bD           Convert input to binary string and duplicate
                 '1011101110', '1011101110'
  γ          Split into groups of 1s or 0s
                 '1011101110', ['1', '0', '111', '0', '111', '0']
   à         Pull out max, parsing each as an integer
                 '1011101110', ['1', '0', '0', '111', '0'], '111'
    Šrk      Rearrange stack and get first index of max run of ones
                 ['1', '0', '0', '111', '0'], 2
       rJg   Reverse stack, join the array to a string, and get its length
                 2, 7
          α  Get absolute difference
                 5

3

J , 18 bis 17 Bytes

(#-0{#\\:#.~\)@#:

Probieren Sie es online!

Erläuterung

(#-0{#\\:#.~\)@#:  Input: integer n
               #:  Binary
     #\            Length of each prefix
       \:          Sorted down using
         #.~\      Mixed base conversion on each prefix
   0{              Get the value at index 0
  -                Subtract from
 #                 Length

Sehr glatt. Ich bin mir nicht sicher, ob ich wirklich verstehe, was mit der gemischten Basiskonvertierung los ist. Warum zählt es die Anzahl der aufeinanderfolgenden am Ende der Zeichenfolge? Wenn die xin der Dyade angegebenen Basen alle 0 und 1 sind, was bedeutet das dann? Eine Basis-2-Nummer hat Ziffern 0und 1, also hat eine Basis- 1Nummer Ziffern ... 0? Was 1bedeutet dann in diesem Zusammenhang? Und ist eine Basisnummer 0nur immer 0?
Jonah

@Jonah Es liegt eher daran, wie die gemischte Basiskonvertierung implementiert wird. x #. yberechnet zuerst w =: */\. }. x , 1und kehrt dann zurück+/ w * y
Meilen

Würden Sie dies als Golf-Hack und nicht als legitimen Einsatz betrachten #., da Sie sich eher auf interne Implementierungsdetails als auf die öffentliche API verlassen?
Jonah,

3

C # (.NET Core) , 64 - 60 Byte

T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)

Probieren Sie es online!

AC # -Version von @ Arnauld's Antwort

Danksagung

Kevin Cruijssen hat 4 Bytes gespart.

C # (.NET Core) , 131 123 + 18 = 141 Byte

a=>{string s=Convert.ToString(a,2),t=s.Split('0').OrderBy(x=>x.Length).Last();return a<1?0:s.Length-s.IndexOf(t)-t.Length;}

Probieren Sie es online!

+18 Bytes für using System.Linq;

Danksagung

Dank Grzegorz Puławski wurden 8 Bytes gespeichert.

Entgolft

a=>{
    string s=Convert.ToString(a,2),      // Convert to binary
    t=s.Split('0')                       // get largest group of 1's
       .OrderBy(x=>x.Length)
       .Last();
    return 
        a<1?0:                          // handle 0 case
        s.Length-s.IndexOf(t)-t.Length; // get position in reversed string
}

C # (.NET Core) , 164 bis 161 Byte

a=>{var s=Convert.ToString(a,2);int c=0,l=0,p=0,k=0,j=s.Length-1,i=j;for(;i>=0;i--){if(s[i]>'0'){if(i==j||s[i+1]<'1'){p=i;c=0;}if(++c>=l){l=c;k=p;}}}return j-k;}

Probieren Sie es online!

Eine Nichtlösung Linq, von der ich sicher bin, dass sie verbessert werden könnte, obwohl nichts sofort offensichtlich ist.

Entgolft

a=>{
    var s=Convert.ToString(a,2); // Convert to binary
    int c=0,l=0,p=0,k=0,j=s.Length-1,i=j;
    for(;i>=0;i--)               // Loop from end of string
    {
        if(s[i]>'0')             // if '1'
        {
            if(i==j||s[i+1]<'1') // if first digit or previous digit was '0'
            {
                p=i;             // set the position of the current group
                c=0;             // reset the count
            }
            if(++c>=l)           // if count is equal or greater than current largest count
            {
                l=c;             // update largest count
                k=p;             // store position for this group
            }
        }
    }
    return j-k;                  // as the string is reversed, return string length minus position of largest group
}

1
Sie können 8 Bytes einsparen, indem Sie rdie erste Antwort verwerfen
Grzegorz Puławski

Sie können zwei Bytes in Ihrem Port von Arnauld 's wie T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
folgt speichern

1
Oder sogar zwei weitere Bytes gespeichert ( 60 Bytes ):T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Kevin Cruijssen

2

Schale , 12 Bytes

→S§-€¤≠Lo▲gḋ

Probieren Sie es online!

Erläuterung

                 Implicit input, e.g                           750
           ḋ     Convert to binary                             [1,0,1,1,1,0,1,1,1,0]
          g      Group equal elements                          [[1],[0],[1,1,1],[0],[1,1,1],[0]]
        o▲       Maximum                                       [1,1,1]
    €            Index of that substring in the binary number  3
     ¤≠L         Absolute difference of lengths                abs (3 - 10) = 7
 S§-             Subtract the two                              7 - 3 = 4
→                Increment                                     5

2

Jelly ,  14 13 12  11 Bytes

Bµṣ0Ṫ$ƤMḢạL

Ein monadischer Link, der nicht negative ganze Zahlen aufnimmt und zurückgibt.

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

Wie?

Bµṣ0Ṫ$ƤMḢạL - Main link: number, n                   e.g. 750
B           - convert to a binary list                    [1,0,1,1,1,0,1,1,1,0]
 µ          - monadic chain separation, call that b
      Ƥ     - map over prefixes:  (i.e. for [1], [1,0], [1,0,1], [1,0,1,1],...)
     $      -   last two links as a monad:                e.g.: [1,0,1,1,1,0,1,1]
   0        -     literal zero                                   0
  ṣ         -     split (prefix) at occurrences of (0)           [[1],[1,1,1],[1,1]]
    Ṫ       -     tail                                                        [1,1]
       M    - maximal indices                             [5,9]
        Ḣ   - head                                        5
          L - length (of b)                               10
         ạ  - absolute difference                         5

Ich hatte eine ähnliche Lösung, verwendete aber ŒrṪPstattdessen die Präfixe.
Meilen

2

Jelly , 19 Bytes

BŒgḄṀB
BwÇɓÇL+ɓBL_‘

Probieren Sie es online!

Vielen Dank an Jonathan Allan für das Speichern von  4 bis  6 Bytes!

Ich habe zu viel gearbeitet, um das aufzugeben, obwohl es ein bisschen lang ist. Ich wollte wirklich eine Lösung hinzufügen, die buchstäblich nach der längsten Teilzeichenfolge von 1s in der Binärdarstellung sucht ...

Erläuterung

BŒgḄṀB - Monadische Hilfsverbindung. Wird mit Ç im nächsten Link verwendet.

B - Binäre Darstellung.
 Œg - Gruppenläufe von aufeinanderfolgenden gleichen Elementen.
   Ḅ - Konvertiert von binär in ganzzahlig.
    Ṁ - Maximalwert.
     B - Konvertiert von Integer zu Binär.


BwÇɓÇL + ɓBL_ '- Hauptlink.

B - Binäre Darstellung (der Eingabe).
  Ç - Letzte Verbindung als Monade. Nimmt die eingegebene Ganzzahl.
 w - Erster Unterlistenindex.
   ɓ - Starten Sie eine separate dyadische Kette. Kehrt die Argumente um.
    Ç - Letzte Verbindung als Monade.
     L - Länge.
      + - Ergänzung
       ɓ - Starten Sie eine separate dyadische Kette. Kehrt die Argumente um.
        B - Binär.
         L - Länge.
          _ '- Subtrahiere und erhöhe das Ergebnis (weil Jelly 1-Indizierung verwendet).
              - Implizit ausgeben.

Ihr Helfer-Link könnte BŒgḄṀBstattdessen sein
Jonathan Allan

@ JonathanAllan Oh wow, danke!
Mr. Xcoder

Ihr Hauptlink könnte seinBwÇɓÇL+ɓBL_‘
Jonathan Allan

@ JonathanAllan Wow, nochmals vielen Dank!
Mr. Xcoder

2

Kotlin , 77 Bytes

{val b=it.toString(2)
b.reversed().lastIndexOf(b.split(Regex("0+")).max()!!)}

Verschönert

{
    val b = it.toString(2)
    // Find the left position of the first instance of
    b.reversed().lastIndexOf(
            // The largest group of 1s
            b.split(Regex("0+")).max()!!)
}

Prüfung

var s:(Int)->Int =
{val b=it.toString(2)
b.reversed().lastIndexOf(b.split(Regex("0+")).max()!!)}
fun main(args: Array<String>) {
    r(0, 0)
    r(142, 1)
    r(48, 4)
    r(750, 5)
}

fun r(i: Int, i1: Int) {
    var v = s(i)
    println("$i -> $v [$i1] ${i1 == v}")
}

Ich habe nicht getestet, denke aber, dass dies auch in Scala funktioniert.
V. Courtois

2

Haskell , 101 98 96 75 Bytes

snd.maximum.(`zip`[0..]).c
c 0=[0]
c n|r<-c$div n 2=sum[r!!0+1|mod n 2>0]:r

Probieren Sie es online! Verbrauch: snd.maximum.(`zip`[0..]).c $ 142Erträge1 .

Erläuterung:

  • cwandelt die Eingabe in Binär um und zählt gleichzeitig die Länge der Streifen von eins, wobei die Ergebnisse in einer Liste gesammelt werden. r<-c$div n 2berechnet rekursiv den Rest rdieser Liste und sum[r!!0+1|mod n 2>0]:rfügt die aktuelle Länge des Streifens hinzu r. Das Listenverständnis prüft mod n 2>0, ob die aktuelle Binärzahl eine Eins ist, und nimmt in diesem Fall die Länge des vorherigen Strichs (des ersten Elements von r) und addiert einen. Ansonsten ist das Listenverständnis leer und sum[]ergibt 0. Für die Beispieleingabe c 142ergibt sich die Liste [0,3,2,1,0,0,0,1,0].

  • (`zip`[0..])Fügt die Position zu jedem Element der vorherigen Liste als zweite Komponente eines Tupels hinzu. Für das Beispiel gibt dies [(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)].

  • maximumfindet das lexikographisch maximale Tupel in dieser Liste, dh die Streifenlängen werden als erste Komponente betrachtet und im Falle eines Unentschieden entscheidet die zweite Komponente, nämlich der größere Index. Dies ergibt (3,1)im Beispiel und sndgibt die zweite Komponente des Tupels zurück.




2

MS SQL Server, 437 426 407 398 Bytes

SQL-Geige

Ich bin mir sicher, dass ich Zeilenumbrüche usw. entfernen könnte, aber das ist so kompakt, wie ich es wollte:

create function j(@ int)
returns int
as BEGIN
declare @a varchar(max)='',@b int,@c int=0,@d int=0,@e int=0,@f int=0,@g int=0,@h int=0
while @>0 BEGIN SELECT @a=cast(@%2 as char(1))+@a,@=@/2
END
SET @b=len(@a)
while @<@b
BEGIN
select @c=@d,@d=cast(substring(@a,@b-@,1)as int)
IF @d=1
BEGIN IF @c=0
SELECT @e=@,@g=1
else SET @g+=1 END
IF @g>=@h BEGIN select @h=@g,@f=@e END
SET @+=1
END
return @f
END

Hier ist eine besser lesbare Version:

create function BinaryString(@id int)
returns int
as BEGIN
  declare @bin varchar(max)
  declare @binLen int
  declare @pVal int = 0
  declare @Val int = 0
  declare @stC int = 0 --start of current string of 1s
  declare @stB int = 0 --start of biggest string of 1s
  declare @lenC int = 0 --length of current string of 1s
  declare @lenB int = 0 --length of biggest string of 1s

  set @bin = ''

    while @id>0
      BEGIN
        SET @bin = cast(@id%2 as varchar(1)) + @bin
        SET @id = @id/2
      END

    SET @binLen = len(@bin)

    while @id<@binLen
      BEGIN
        set @pVal = @Val
        set @Val = cast(substring(@bin,@binLen-@id,1) as int)
        IF @Val = 1 and @pVal = 0
          BEGIN 
            SET @stC = @id
            SET @lenC = 1
          END
        IF @Val = 1 and @pVal = 1
          BEGIN 
            SET @lenC = @lenC + 1
          END
        IF @lenC >= @lenB
          BEGIN
            set @lenB = @lenC
            set @StB = @StC
          END

        SET @id = @id + 1 
      END

  return @StB
END

Der eigentliche Trick ist, dass es meines Erachtens keine native SQL-Funktionalität gibt, um eine Zahl von dezimal in binär umzuwandeln. Infolgedessen musste ich die Umwandlung in eine Binärdatei manuell codieren, und dann konnte ich diese als Zeichenfolge einzeln vergleichen, bis ich die richtige Zahl gefunden hatte.

Ich bin mir sicher, dass es einen besseren Weg gibt, aber ich habe keine (n) SQL-Antwort erhalten.


Wenn Sie mehr Golf spielen können, tun Sie dies bitte. Aber sonst ist das super! Willkommen bei PPCG!
NoOneIsHere

@NoOneIsHere danke! Mir wurde klar, dass ich meinen Funktionsnamen auch kürzen kann;)
Phroureo

2

APL (Dyalog Unicode) , 22 Zeichen = 53 Byte

Benötigt, ⎕IO←0was auf vielen Systemen Standard ist.

⊃⌽⍸(∨⌿↑⊆⍨b)⍷⌽b2⊥⍣¯1⊢⎕

Probieren Sie es online!

 Eingabeaufforderung

 ergeben, dass (trennt sich ¯1von )

2⊥⍣¯1 konvertiere zu base-2 und verwende so viele positionen wie nötig

b← speichern als b(für b inary)

 umkehren

() Markieren Sie die Startpositionen von Folgendem:

⊆⍨b Selbstpartitionierung b(dh die 1-Streifen von b)

 mischen (Liste der Listen in Matrix umwandeln, mit Nullen auffüllen)

∨⌿ vertikale OP-Reduktion (ergibt die längste Strichstärke)

ɩ zu den Startpositionen

 umkehren

 wähle die erste aus (ergibt null, wenn keine verfügbar ist)


Sie sind ein ∇ in der Fußzeile auf tio fehlt
ngn

@ngn Richtig.
Adám

1

MATL , 15 Bytes

`tt2/kZ&t]xBnq&

Probieren Sie es online!

Verwendet die Hälfte und UND-Idee. Das kist nur notwendig, um es zu beenden1 - aus irgendeinem Grund gibt 1 AND 0.5 1 zurück und verursacht eine Endlosschleife.

(Alternative Lösung: BtnwY'tYswb*&X>)-durch Konvertieren in Binär- und Lauflängencodierung)


1

Google Sheets, 94 Bytes

=Len(Dec2Bin(A1))-Find(MAX(Split(Dec2Bin(A1),0)),Dec2Bin(A1))-Len(MAX(Split(Dec2Bin(A1),0)))+1

Nein, es ist nicht sehr hübsch. Es wäre wirklich schön, etwas lagern zu könnenDec2Bin(A1) Referenzvariable .

Wichtig: Die Dec2BinFunktion hat wie Excel einen maximalen Eingabewert von 511. Alles, was größer ist, gibt einen Fehler zurück (siehe unten).

Ergebnisse


1

R, 117 Bytes

z=rev(Reduce(function(x,y)ifelse(y==1,x+y,y),strtoi(intToBits(scan())),,,T));ifelse(!sum(z),0,33-which.max(z)-max(z))

104 Bytes! revVerwenden Sie stattdessen , um Reduce(...,T,T)von rechts zu akkumulieren (Umschalten x,yin der Funktionsdefinition). Dann benutze 1+max(z)-which.max(z)da das Ergebnis etwas anders. Verwenden Sie "if"anstelle von, "ifelse"da wir die Vektorisierung nicht benötigen. und wenn Sie any(z)stattdessen verwenden, löschen Sie !sum(z)ein Byte.
Giuseppe

Ich denke, wir sollten in der Lage sein, dies auf weniger als 100 Bytes zu bringen.
Giuseppe

@giuseppe Ich fühle mich ein bisschen betrogen, hier vor dir zu sein! Werde mal ein paar tnx machen!
Zahiro Mor

Aber ein schöner Ansatz, nein?
Zahiro Mor

1
Oh, keine Sorge, ich sah zu Beginn dieses aber hatte keine Lust , sie zu beantworten , weil R so schlecht Bit - Operationen ist ... Ja, gute Arbeit, Sie haben meine +1
Giuseppe

1

Excel VBA, 54 44 Bytes

-10 Bytes dank @EngineerToast

Anonyme VBE-Direktfensterfunktion, die Eingaben aus dem Bereich [A1]und Ausgaben in das VBE-Direktfenster übernimmt

?Instr(1,StrReverse([Dec2Bin(A1)]),1)+[A1>0]

1
Abgesehen davon, dass das Versehen C1immer noch vorhanden A1ist, kann man die InstrErgebnisse meiner Meinung nach mit ein wenig Drehung für die Nullpunktkorrektur direkt ausgeben : ?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0)(46 Bytes). True = -1 weil ... VBA.
Ingenieur Toast

@EngineerToast - Süß! Ich hätte das sehen sollen. Ich konnte es auf 2 Bytes fallen durch die bringen >0in die [A1]Notation
Taylor Scott



0

R, 66 Bytes

function(i){a=rle(intToBits(i));max(0,a[[1]][which(a[[2]]==1)])}

Erläuterung:

function(i){
  a = rle(                  # Run-length encode
    intToBits(i)            # The bits in i
  );                        # And assign it to a.
  max(0,                    # Return the maximum of zero and
      a[[1]][               # The lengths of a,
        which(a[[2]]==1)    # But only those where the repeated bit is 1
        ])
}

1
Dies gibt die Länge des längsten Streifens und nicht seine Position zurück. Vergleichen Sie die Testfälle mit den Angaben oben.
user2390246

Ich werde meine Gegenstimme in eine Gegenstimme ändern, sobald diese Antwort korrigiert ist. Beachten Sie auch, dass Sie a$lanstelle von a[[1]]und a$vanstelle von a[[2]]einige Bytes speichern können :) sowie >0anstelle von ==1.
Giuseppe


0

Javascript, 54 Zeichen

f=i=>i.toString(2).split(0).sort().reverse()[0].length
  • i.toString(2) Ruft die Binärzeichenfolge für die Ganzzahl ab.
  • Das .split(0)ruft jeden sequentiellen Teil in einem Array-Element ab.
  • .sort().reverse() bringt uns als erstes den höchsten wert.
  • Das [0].lengthgibt uns die Länge dieses ersten Wertes.

the starting position of number of largest consecutive 1's
L3viathan

0

Perl 5, 45 + 1 (-p)

(sprintf"%b",$_)=~/(1+)(?!.*1\1)/;$_=length$'

Wenn Sie dies in die Befehlszeile der meisten Shells schreiben, müssen Sie dies möglicherweise wie folgt eingeben:

perl -pE'(sprintf"%b",$_)=~/(1+)(?!.*1\1)/;$_=length$'"'"

Der Tanz der Zitate am Ende ist nur, um Perl zu sehen ', was sonst von der Shell verzehrt würde.


0

Netzhaut , 52 43 Bytes

In Binärdatei konvertieren und durch die Länge der größten Folge von Einsen ersetzen.

.*
$*
+`(1+)\1
$+0
01
1

$'¶
O`
A-3`
^1+

.

Probieren Sie es online aus - alle Testfälle

9 Bytes gespart dank Martin.


Sie können $+für verwenden ${1}. Sie können jedoch noch mehr sparen, indem Sie die letzte Stufe durch eine Reihe von Stufen ersetzen : tio.run/##K0otycxL/K/…
Martin Ender

@ MartinEnder Ok. Das ${1}wurde aus deinem Tutorial auf Github kopiert.
mbomb007
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.