Oblicz najdłuższą serię 1 w wartości binarnej liczby całkowitej

32

Cel

Biorąc pod uwagę nieujemną liczbę całkowitą, utwórz funkcję, która zwraca pozycję początkową liczby największych kolejnych 1 w wartości binarnej tej liczby całkowitej.

Po otrzymaniu danych wejściowych 0powróć 0.

Jeśli liczba ma wiele pasów o równej długości, musisz zwrócić pozycję ostatniej pasma.

Wkład

Liczba całkowita większa lub równa 0.

Wydajność

Liczba całkowita obliczona jak wyjaśniono poniżej.

Zasady

  • To jest golf golfowy, więc wygrywa najkrótszy kod w bajtach w każdym języku.
  • Standardowe luki są zabronione.

Przykłady i przypadki testowe

Przykład 1

  • Twoja funkcja ma liczbę całkowitą 142
  • 142 jest równa 10001110 w systemie binarnym
  • Najdłuższa seria to „111” (seria trzech)
  • Smuga zaczyna się od pozycji 2 ^ 1
  • Twoja funkcja zwraca 1 jako wynik

Przykład 2

  • Twoja funkcja ma liczbę całkowitą 48
  • 48 jest równa 110000 w systemie binarnym
  • Najdłuższa seria to „11” (seria dwóch)
  • Seria zaczyna się od pozycji 2 ^ 4
  • Twoja funkcja zwraca 4 jako wynik

Przykład 3

  • Twoja funkcja ma liczbę całkowitą 750
  • 750 jest równa 1011101110 w systemie binarnym
  • Najdłuższa seria to „111” (seria trzech)
  • Ponieważ są dwie smugi o równej długości, zwracamy później smugę.
  • Późniejsza seria rozpoczyna się od pozycji 2 ^ 5
  • Twoja funkcja zwraca 5 jako wynik
Defacto
źródło
1
Potrzebujesz wygrywającego kryterium, takiego jak golf
kodowy
@Okx Zostało to wspomniane w samym ciele, więc dodałem tag.
całkowicieludzki
Upewnij się, że ludzie testują 0. To ważny przypadek testowy.
mbomb007
2
Zamiast „ostatniej serii” lub „ostatniej serii” sugerowałbym „serię z największą wartością miejsca”.
aschepler
@Okx Dlaczego konieczne jest kryterium wygranej? Dlaczego to nie może być po prostu łamigłówka?
corsiKa

Odpowiedzi:

21

Galaretka , 10 8 bajtów

Ba\ÐƤṀċ¬

Wypróbuj online!

Jak to działa

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.
Dennis
źródło
Gratulacje!
Defacto,
24

JavaScript (ES6), 41 40 36 34 bajtów

Zaoszczędź 4 bajty dzięki @ThePirateBay

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

Przypadki testowe

W jaki sposób?

Przypadek ogólny x> 0

Rekurencyjnie ORAZ wejście x za pomocą x / 2, które stopniowo zmniejsza wzorce kolejnych ustawionych bitów, aż pozostanie tylko najbardziej prawy bit sekwencji. Przechowujemy kopię ostatniej niezerowej wartości i określamy pozycję jej najbardziej znaczącego bitu, zaokrąglając podłogę do logarytmu podstawy 2.

Poniżej znajdują się kroki, które wykonujemy dla x = 750 ( 1011101110 w systemie binarnym).

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

Przypadek krawędzi x = 0

Specjalny przypadek x = 0natychmiast prowadzi do Math.log2(0) | 0. Logarytm 0wartościowania -Infinityi binarna OR bitowa wymusza przymus na 32-bitową liczbę całkowitą. Zgodnie ze specyfikacją abstrakcyjnej operacji ToInt32 daje to oczekiwane 0:

Jeśli liczba to NaN , +0 , −0 , + ∞ lub −∞ , zwróć +0

Arnauld
źródło
To błędy dla danych wejściowych 0, które są częścią zakresu wejściowego.
Justin Mariner
@JustinMariner Naprawiono.
Arnauld,
Co powiesz na Math.log2(k)|0zamiast 31-Math.clz32(k)? A może coś mi brakuje?
@ThePirateBay Math.log2(k)|0jest w rzeczywistości zarówno krótszy, jak i prostszy w specjalnym przypadku x=0. Dzięki. :)
Arnauld,
1
Bardzo fajny algorytm i dobre wyjaśnienie. Zaimplementowałem go w 14 bajtach kodu maszynowego x86 .
Peter Cordes,
12

kod maszynowy x86, 14 bajtów

Korzystanie @ algorytmu Arnauld za dnia x &= x>>1i biorąc najwyższą ustaloną pozycję bit w kroku zanim xstaje 0.

Możliwość wywołania z C / C ++ z podpisem unsigned longest_set(unsigned edi);w x86-64 System V ABI. Te same bajty kodu maszynowego będą dekodowane w ten sam sposób w trybie 32-bitowym, ale standardowe 32-bitowe konwencje wywoływania nie umieszczają pierwszego argumentu edi. (Zmiana rejestru wejściowego na ecxlub edxna Windows _fastcall/ _vectorcalllub gcc -mregparmmoże być wykonana bez zerwania czegokolwiek.)

   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

BSRInstrukcja x86 (Bit Scan Reverse) jest do tego idealna, dając nam bezpośrednio indeks bitowy, zamiast zliczać wiodące zera. ( bsrnie tworzy bezpośrednio 0 dla wejścia = 0, tak jak 32-lzcnt(x)byśmy potrzebowali, ale potrzebujemy bsr = 31-lzcnt dla niezerowych danych wejściowych, więc lzcntnawet nie zapisałbym instrukcji, nie mówiąc już o liczeniu bajtów. Zerowanie eax przed pętlą działa z powodu bsr' s półoficjalne zachowanie pozostawiania celu niezmodyfikowanego, gdy wartość wejściowa wynosi zero).

Byłoby to jeszcze krótsze, gdybyśmy mogli zwrócić pozycję MSB najdłuższego biegu. W takim przypadku lea ecx, [rdi+rdi](3 bajty) skopiuje + lewy Shift zamiast mov+ shr(4 bajty).

Zobacz ten link TIO dla dzwoniącego asm, który to robiexit(longest_set(argc-1));

Testowanie za pomocą pętli powłoki:

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
Peter Cordes
źródło
1
Miły! Uwaga dla tych, którzy (jak ja) są bardziej zaznajomieni z innymi dialektami asemblera: mnemonik x86 BSR oznacza „Bit Scan Reverse”, a nie „Branch to SubRoutine”.
Arnauld,
@Arnauld: dobry punkt, edytowany w celu zdekodowania mnemonika, a także mający link do ręcznego wpisu referencji insn.
Peter Cordes,
5

Galaretka , 19 17 11 bajtów

HÐĿ&\ḟ0ṪBL’

Wypróbuj online!

-6 (!) Bajtów dzięki bystrym obserwacjom @ Dennisa

Jak to działa

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
fireflame241
źródło
Błędy dla 0, który jest w zakresie wejściowym.
Pan Xcoder,
@ Mr.Xcoder Naprawiono
fireflame241
Możesz zapisać bajt dla poprawki za pomocąȯ-µ...
Jonathan Allan
@JonathanAllan Nie rozumiem, w jaki sposób pomogłoby OR-ing. Czy masz kod
fireflame241
1
Ponieważ Bzawsze zwraca tablicę rozpoczynającą się od 1 , BUṪMṪ’×Ṡmoże się stać ṪBL’. Ponadto nie potrzebujesz i ḟ0oszczędzasz jeden bajt ¹Ðf.
Dennis
5

Python 2 , 45 bajtów

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

Wypróbuj online!

Zaoszczędź mnóstwo bajtów dzięki Dennis! (Heads up len(bin(...))-3zamiast zamiast math.frexp)

Dzięki @xnor za znalezienie błędu, który na szczęście łatwo było naprawić!

Pan Xcoder
źródło
Wydaje się, że daje to błędne odpowiedzi, takie jak x=3, jak sądzę, ponieważ and/orzwarcia są nieprawidłowe, gdy funkcja zwraca 0.
xnor 18.09.17
@xnor Dziękujemy za zauważenie tego! Jest naprawione.
Pan Xcoder,
4

Perl 6 ,45 35 bajtów

Ta wysoce ulepszona wersja udostępniona dzięki uprzejmości @nwellnhof.

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

Wypróbuj online!

Ramillies
źródło
Możesz po prostu dopasować, :gaby uzyskać wszystkie dopasowania. Dzięki operatorowi smart-matchu mogłem {sort(.base(2).flip~~m:g/1+/).tail.from}
zagrać w
I do 35 bajtów:{.msb+1-(.base(2)~~m:g/1+/).max.to}
nwellnhof
@nwellnhof, dziękuję bardzo. Jakoś przegapiłem :gi nie wymyśliłem, jak mogę używać przysłówka z operatorem smartmatch. Również .msbmetoda jest tutaj bardzo pomocna i wcześniej o niej nie wiedziałem.
Ramillies,
3

Python 2 , 89 78 bajtów

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

Wypróbuj online!

EDYCJA: Oszczędź 11 bajtów dzięki Mr. Xcoder.

Chas Brown
źródło
86 bajtów
pan Xcoder,
78 bajtów
pan Xcoder,
@ Mr.Xcoder Też o tym pomyślałem, chociaż pytanie dotyczy konkretnie napisania funkcji.
Jonathan Frech,
@JathanathanFrech Nie sądzę, żeby OP miał na myśli funkcję . Prawdopodobnie tylko ogólny termin.
Pan Xcoder,
@ Mr.Xcoder Wyjaśnij to. Dzięki,
lifebalance
3

05AB1E , 14 12 11 bajtów

bDγàŠrkrJgα

Wypróbuj online! lub uruchom przypadki testowe .

Wyjaśnienie

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
Justin Mariner
źródło
3

J , 18 17 bajtów

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

Wypróbuj online!

Wyjaśnienie

(#-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
mile
źródło
Bardzo zręczny. Nie jestem jednak pewien, czy w pełni rozumiem, co się dzieje z konwersją mieszanej bazy. Dlaczego liczy liczbę kolejnych na końcu ciągu? Ponadto, jeśli wszystkie zasady podane na xdiadadzie mają wartość 0 i 1, co to oznacza? Numer bazowy 2 ma cyfry, 0a 1więc 1numer bazowy ma cyfry ... 0? co zatem 1oznacza w tym kontekście? I czy 0liczba podstawowa jest zawsze zawsze 0?
Jonasz
@Jonah To bardziej ze względu na sposób implementacji konwersji mieszanej podstawy. x #. ynajpierw oblicza, w =: */\. }. x , 1a potem wraca+/ w * y
mile
więc czy uznałbyś to za hack golfowy, a nie za uzasadnione użycie #., ponieważ polegasz na wewnętrznych szczegółach implementacyjnych, a nie na publicznym API?
Jonasz
3

C # (.NET Core) , 64 60 bajtów

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

Wypróbuj online!

AC # wersja odpowiedzi @ Arnauld

Podziękowanie

4 bajty zapisane dzięki Kevin Cruijssen.

C # (.NET Core) , 131 123 + 18 = 141 bajtów

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;}

Wypróbuj online!

+18 bajtów dla using System.Linq;

Podziękowanie

8 bajtów zaoszczędzonych dzięki Grzegorzowi Puławskiemu.

Degolfed

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 161 bajtów

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;}

Wypróbuj online!

To nierozwiązanie Linq, które z pewnością można poprawić, choć nic nie jest od razu widoczne.

Degolfed

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
}
Ayb4btu
źródło
1
Możesz zapisać 8 bajtów, porzucając rpierwszą odpowiedź: tio.run/##dY9RS8MwFIWfza/…
Grzegorz Puławski
Możesz zapisać dwa bajty w swoim porcie Arnaulda w następujący sposób:T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
Kevin Cruijssen
1
Albo jeszcze dwa zapisane bajty ( 60 bajtów ):T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Kevin Cruijssen
2

Łuska , 12 bajtów

→S§-€¤≠Lo▲gḋ

Wypróbuj online!

Wyjaśnienie

                 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
H.PWiz
źródło
2

Galaretka ,  14 13 12  11 bajtów

Bµṣ0Ṫ$ƤMḢạL

Łącze monadyczne przyjmujące i zwracające nieujemne liczby całkowite.

Wypróbuj online! lub zobacz zestaw testowy .

W jaki sposób?

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
Jonathan Allan
źródło
Miałem podobne rozwiązanie, ale ŒrṪPzamiast tego użyłem prefiksów.
mile
2

Galaretka , 19 bajtów

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

Wypróbuj online!

Dziękujemy Jonathanowi Allanowi za uratowanie  4  6 bajtów!

Za dużo pracowałem, żeby to porzucić, choć to trochę za długo. Naprawdę chciałem dodać rozwiązanie, które dosłownie wyszukuje najdłuższe podciągi 1w reprezentacji binarnej ...

Wyjaśnienie

BŒgḄṀB - Monadic link pomocnika. Zostanie użyty z Ç w następnym linku.

B - Reprezentacja binarna.
 --G - Grupowe serie kolejnych równych elementów.
   Ḅ - Konwertuj z binarnej na całkowitą.
    Ṁ - Maksymalna wartość.
     B - Konwertuj z liczb całkowitych na binarne.


BwÇɓÇL + ɓBL_ '- Główny link.

B - Reprezentacja binarna (wejścia).
  Ç - Ostatni link jako monada. Pobiera wejściową liczbę całkowitą.
 w - Pierwszy indeks podlisty.
   ɓ - Rozpocznij oddzielny łańcuch dyadiczny. Odwraca argumenty.
    Ç - Ostatni link jako monada.
     L - długość.
      + - Dodawanie
       ɓ - Rozpocznij oddzielny łańcuch dyadiczny. Odwraca argumenty.
        B - Binarny.
         L - długość.
          _ '- Odejmij i zwiększ wynik (ponieważ Jelly używa indeksowania 1).
              - Wyjściowy wynik.
Pan Xcoder
źródło
Twój link pomocnika może być BŒgḄṀBzamiast tego
Jonathan Allan
@JonathanAllan Oh wow dzięki!
Pan Xcoder,
Twój główny link może byćBwÇɓÇL+ɓBL_‘
Jonathan Allan
@JonathanAllan Wow, jeszcze raz dziękuję!
Pan Xcoder,
2

Kotlin , 77 bajtów

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

Upiększony

{
    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()!!)
}

Test

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}")
}
jrtapsell
źródło
Nie testowałem, ale sądzę, że to też działa w Scali.
V. Courtois,
2

Haskell , 101 98 96 75 bajtów

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

Wypróbuj online! Zastosowanie: snd.maximum.(`zip`[0..]).c $ 142plony 1.

Wyjaśnienie:

  • ckonwertuje dane wejściowe na binarne, jednocześnie licząc długość pasm jednego, zbierając wyniki na liście. r<-c$div n 2rekurencyjnie oblicza resztę rtej listy, jednocześnie sum[r!!0+1|mod n 2>0]:rdodając bieżącą długość pasma r. Zrozumienie listy sprawdza, czy mod n 2>0to znaczy, czy bieżąca cyfra binarna to jedna, a jeśli tak, bierze długość poprzedniej serii (pierwszy element r) i dodaje jedną. W przeciwnym razie zrozumienie listy jest puste i sum[]daje wynik 0. Dla przykładowego wejścia c 142zwraca listę [0,3,2,1,0,0,0,1,0].

  • (`zip`[0..])dodaje pozycję do każdego elementu z poprzedniej listy jako drugi składnik krotki. Na przykład daje to [(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)].

  • maximumznajduje leksykograficznie maksymalną krotkę na tej liście, to znaczy długości smug są uważane za pierwsze, ponieważ są one pierwszym składnikiem, aw przypadku powiązania decyduje drugi składnik, a mianowicie większy indeks. Daje to (3,1)w przykładzie i sndzwraca drugi składnik krotki.

Laikoni
źródło
2

C (gcc) , 81 80 bajtów

i,l,c,r;f(n){for(i=l=c=r=0;n;n/=2,i++)c=n&1?c+1:c>=l?r=i-(l=c),0:0;n=c<l?r:i-c;}

Wypróbuj online!

C (gcc) , 43 bajty

Wersja AC odpowiedzi @ Arnauld

k;f(n){n=(k=n&n/2)?f(k):(k=log2(n))<0?0:k;}

Wypróbuj online!

cleblanc
źródło
Przegap powrót n; lub zwróć k; oświadczenie
RosLuP,
Zaproponuj n<1?0:log2(n)zamiast(k=log2(n))<0?0:k
ceilingcat
2

MS SQL Server, 437 426 407 398 bajtów

SQL Fiddle

Jestem pewien, że mógłbym usunąć podziały linii itp., Ale jest to tak kompaktowe, jak chciałem to zrobić:

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

Oto bardziej czytelna wersja:

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

Prawdziwa sztuczka polega na tym, że o ile mogłem znaleźć, nie ma natywnej funkcjonalności SQL do konwersji liczby z dziesiętnej na binarną. W rezultacie musiałem ręcznie zakodować konwersję do pliku binarnego, a następnie mogłem porównać to jako ciąg, jeden znak na raz, aż znajdę właściwą liczbę.

Jestem pewien, że jest lepszy sposób, aby to zrobić, ale nie widziałem (n) odpowiedzi SQL, więc pomyślałem, że ją tam wyrzucę.

froureo
źródło
Jeśli możesz pograć bardziej w golfa, zrób to. Ale poza tym jest świetnie! Witamy w PPCG!
NoOneIsHere
@NoOneIsHere dzięki! Zdałem sobie sprawę, że mogę także skrócić nazwę mojej funkcji;)
phroureo
2

APL (Dyalog Unicode) , 22 znaki = 53 bajty

Wymaga ⎕IO←0ustawienia domyślnego w wielu systemach.

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

Wypróbuj online!

 monit o wprowadzenie

 dochód, (wydzielane ¯1z )

2⊥⍣¯1 przekonwertować na base-2, używając tyle pozycji, ile potrzeba

b← przechować b(dla b inary)

 rewers

() Zaznacz pozycje początkowe następujących pozycji:

⊆⍨b samo-podział b(tj. 1-pasmowy b)

 mix (zmień listę list w macierz, dopełnianie zerami)

∨⌿ redukcja pionowa OR (daje najdłuższą smugę)

Wskaźniki pozycji początkowych

 rewers

 wybierz pierwszy (daje zero, jeśli nie jest dostępny)

Adám
źródło
brakuje ∇ w stopce na tio
ngn
@ngn Masz rację.
Adám
1

MATL , 15 bajtów

`tt2/kZ&t]xBnq&

Wypróbuj online!

Wykorzystuje połowę i AND. Jest kto konieczne tylko po to, aby zakończyć działanie 1- z jakiegoś powodu 1 ORAZ 0,5 zwraca 1, powodując nieskończoną pętlę.

(alternatywne rozwiązanie: BtnwY'tYswb*&X>)-przez konwersję na kodowanie binarne i długość przebiegu)

B. Mehta
źródło
1

Arkusze Google, 94 bajty

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

Nie, to nie jest bardzo ładne. Byłoby naprawdę miło móc przechowywać Dec2Bin(A1)jako zmienną w celach informacyjnych.

Kluczowy punkt: Podobnie jak Excel, Dec2Binfunkcja ma maksymalną wartość wejściową wynoszącą 511. Wszystko większe niż to zwraca błąd, jak pokazano poniżej.

Wyniki

Inżynier Toast
źródło
1

R, 117 bajtów

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))
Zahiro Mor
źródło
104 bajty! Zamiast rev, użyj Reduce(...,T,T)do kumulowania od prawej (przełączanie x,ydefinicji funkcji). Następnie użyj, 1+max(z)-which.max(z)ponieważ wynik jest nieco inny. Użyj "if"zamiast, "ifelse"ponieważ nie potrzebujemy wektoryzacji; a jeśli użyjesz any(z)zamiast tego !sum(z)upuść bajt.
Giuseppe,
Myślę, że powinniśmy być w stanie doprowadzić to do mniej niż 100 bajtów.
Giuseppe,
@giuseppe Czuję się nieco oszustem za bycie tutaj przed tobą! Zrobię razy kilka razy!
Zahiro Mor,
Ale ładne podejście nie?
Zahiro Mor,
1
Och, nie martw się, widziałem to wcześniej, ale nie miałem ochoty na to odpowiadać, ponieważ R jest tak zły w operacjach bitowych ... Tak, dobra robota, dostałeś moją +1
Giuseppe
1

Excel VBA, 54 44 bajtów

-10 Bajtów dzięki @EngineerToast

Anonimowa funkcja bezpośredniego okna VBE, która przenosi dane wejściowe z zakresu [A1]i wyjścia do bezpośredniego okna VBE

?Instr(1,StrReverse([Dec2Bin(A1)]),1)+[A1>0]
Taylor Scott
źródło
1
Poza tym nadzorem, który C1wciąż tam jest A1, myślę, że możesz wyprowadzać Instrwyniki bezpośrednio z niewielkim przekręceniem dla zerowej korekcji wejściowej: ?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0)(46 bajtów). Prawda = -1, ponieważ ... VBA.
Engineer Toast
@EngineerToast - Sweet! Powinienem to zobaczyć; Udało mi się upuścić go w dół 2 bajty wnosząc >0do [A1]notacji
Taylor Scott
0

R, 66 bajtów

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

Wyjaśnienie:

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
        ])
}
Julian Zucker
źródło
1
Zwraca długość najdłuższej serii, a nie jej pozycję. Sprawdź przypadki testowe i specyfikacje u góry.
user2390246,
Po poprawieniu tej odpowiedzi zmienię zdanie negatywne na głosowanie pozytywne. Zauważ też, że możesz użyć a$lzamiast a[[1]]i a$vzamiast, a[[2]]aby zapisać niektóre bajty :), a także >0zamiast ==1.
Giuseppe,
0

JavaScript, 54 znaki

f=i=>i.toString(2).split(0).sort().reverse()[0].length
  • i.toString(2) pobiera ciąg binarny dla liczby całkowitej.
  • .split(0)Dostaje każdy sekwencyjną jedynek udział w elemencie tablicy.
  • .sort().reverse() dostaje pierwszą najwyższą wartość.
  • [0].lengthDaje nam długość tej pierwszej wartości.
nl-x
źródło
the starting position of number of largest consecutive 1's
L3viathan
0

Perl 5, 45 + 1 (-p)

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

Jeśli wypiszesz to w wierszu poleceń większości powłok, być może będziesz musiał wpisać to jako:

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

Taniec cytatów na końcu polega na tym, aby perl zobaczył a ', który w innym przypadku zostałby zużyty przez powłokę.


źródło
0

Siatkówka , 52 43 bajty

Konwertuj na binarny, a następnie zamień na długość ciągu największego z nich.

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

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

.

Wypróbuj online - wszystkie przypadki testowe

Zaoszczędź 9 bajtów dzięki Martinowi.

mbomb007
źródło
Możesz użyć $+do ${1}. Ale możesz zaoszczędzić jeszcze więcej, zastępując ostatni etap kilkoma etapami: tio.run
Martin Ender
@MartinEnder Ok. ${1}Została skopiowana z samouczka na Github.
mbomb007