Hitung seri terlama dari 1 dalam nilai biner integer

32

Tujuan

Dengan bilangan bulat non-negatif, buat fungsi yang mengembalikan posisi awal jumlah 1 terbesar berturut-turut dalam nilai biner bilangan bulat itu.

Saat diberi input 0, kembali 0.

Jika angka memiliki beberapa goresan dengan panjang yang sama, Anda harus mengembalikan posisi goresan terakhir.

Memasukkan

Integer lebih besar dari atau sama dengan 0.

Keluaran

Bilangan bulat dihitung seperti dijelaskan di bawah ini.

Aturan

  • Ini adalah kode-golf, jadi kode terpendek dalam byte di setiap bahasa menang.
  • Celah standar dilarang.

Contoh dan Kasus Uji

Contoh 1

  • Fungsi Anda melewati bilangan bulat 142
  • 142 sama dengan 10001110 dalam biner
  • Coretan terpanjang adalah "111" (coretan tiga yang)
  • Garis mulai pada posisi 2 ^ 1
  • Fungsi Anda mengembalikan 1 sebagai hasilnya

Contoh 2

  • Fungsi Anda melewati integer 48
  • 48 sama dengan 110000 dalam biner
  • Coretan terpanjang adalah "11" (coretan dua yang)
  • Garis mulai pada posisi 2 ^ 4
  • Fungsi Anda mengembalikan 4 sebagai hasilnya

Contoh 3

  • Fungsi Anda melewati bilangan bulat 750
  • 750 sama dengan 1011101110 dalam biner
  • Coretan terpanjang adalah "111" (coretan tiga yang)
  • Karena ada dua garis dengan panjang yang sama, kami mengembalikan garis selanjutnya.
  • Coretan selanjutnya dimulai pada posisi 2 ^ 5
  • Fungsi Anda mengembalikan 5 sebagai hasilnya
Defacto
sumber
1
Anda memerlukan kriteria kemenangan, seperti kode-golf
Okx
@ Okx Sudah disebutkan dalam tubuh itu sendiri jadi saya menambahkan tag.
totallyhuman
Pastikan orang menguji 0. Itu adalah ujian penting.
mbomb007
2
Alih-alih "coretan terakhir" atau "coretan terbaru", saya sarankan "coret dengan nilai tempat terbesar".
aschepler
@Okx Mengapa kriteria kemenangan diperlukan? Mengapa itu tidak bisa menjadi teka-teki?
corsiKa

Jawaban:

21

Jelly , 10 8 byte

Ba\ÐƤṀċ¬

Cobalah online!

Bagaimana itu bekerja

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
sumber
Selamat!
Defacto
24

JavaScript (ES6), 41 40 36 34 byte

Disimpan 4 byte berkat @ThePirateBay

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

Uji kasus

Bagaimana?

Kasus umum x> 0

Kami secara rekursif DAN input x dengan x / 2 yang secara progresif mengurangi pola bit set berurutan hingga hanya bit paling kanan dari urutan yang tersisa. Kami menyimpan salinan dari nilai non-nol terakhir dan menentukan posisi bit paling signifikan dengan membulatkan logaritma basis-2.

Berikut adalah langkah-langkah yang kami lalui untuk x = 750 ( 1011101110 dalam biner).

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

Kasing tepi x = 0

Kasus khusus x = 0segera mengarah ke Math.log2(0) | 0. Logaritma dari 0evaluasi ke -Infinitydan bitwise biner ATAU memaksa pemaksaan ke bilangan bulat 32-bit. Sesuai dengan spesifikasi operasi abstrak ToInt32 , ini memberikan yang diharapkan 0:

Jika angka adalah NaN , +0 , −0 , + ∞ , atau −∞ , kembalikan +0

Arnauld
sumber
Ini kesalahan untuk input 0, yang merupakan bagian dari rentang input.
Justin Mariner
@JustinMariner Diperbaiki.
Arnauld
Bagaimana dengan Math.log2(k)|0sebaliknya 31-Math.clz32(k)? Atau apakah saya melewatkan sesuatu?
@ThePirateBay Math.log2(k)|0sebenarnya lebih pendek dan lebih sederhana untuk kasus khusus x=0. Terima kasih. :)
Arnauld
1
Algoritma yang sangat bagus, dan penjelasan yang bagus. Saya menerapkannya dalam 14 byte kode mesin x86 .
Peter Cordes
12

kode mesin x86, 14 byte

Menggunakan @ algoritma Arnauld ini dari x &= x>>1dan mengambil set posisi bit tertinggi pada langkah sebelumnya xmenjadi 0.

Dipanggil dari C / C ++ dengan tanda tangan unsigned longest_set(unsigned edi);di Sistem V86 ABI x86-64. Byte kode mesin yang sama akan mendekode dengan cara yang sama dalam mode 32-bit, tetapi konvensi pemanggilan standar 32-bit tidak memasukkan arg pertama edi. (Mengubah register input ke ecxatau edxuntuk Windows _fastcall/ _vectorcallatau gcc -mregparmdapat dilakukan tanpa merusak apa pun.)

   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

BSRInstruksi x86 (Bit Scan Reverse) sangat cocok untuk ini, memberikan kami indeks-bit secara langsung, daripada menghitung angka nol di depan. ( bsrtidak secara langsung menghasilkan 0 untuk input = 0 seperti 32-lzcnt(x)akan, tetapi kita perlu bsr = 31-lzcnt untuk input non-nol, jadi lzcntbahkan tidak akan menyimpan instruksi, apalagi jumlah byte. Mem-kosongkan eax sebelum loop bekerja karenabsr ' perilaku setengah resmi meninggalkan tujuan tidak dimodifikasi ketika inputnya nol.)

Ini akan menjadi lebih pendek jika kita dapat mengembalikan posisi MSB dari perjalanan terpanjang. Dalam hal ini, lea ecx, [rdi+rdi](3 byte) akan menyalin + kiri- alih alih-alih mov+ shr(4 byte).

Lihat tautan TIO ini untuk pemanggil asm yang melakukannyaexit(longest_set(argc-1));

Pengujian dengan loop shell:

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
sumber
1
Bagus! Catatan untuk mereka yang (seperti saya) lebih akrab dengan dialek rakitan lainnya: mnemonic x86 BSR singkatan dari "Bit Scan Reverse", bukan "Branch to SubRoutine".
Arnauld
@Arnauld: poin bagus, diedit untuk memecahkan kode mnemonic serta memiliki tautan ke entri manual referensi insn.
Peter Cordes
5

Jelly , 19 17 11 byte

HÐĿ&\ḟ0ṪBL’

Cobalah online!

-6 (!) Byte berkat pengamatan tajam @ Dennis

Bagaimana itu bekerja

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
sumber
Kesalahan untuk 0, yang ada dalam rentang input.
Tn. Xcoder
@ Mr.Xcoder Tetap
fireflame241
Anda dapat menyimpan byte untuk perbaikan denganȯ-µ...
Jonathan Allan
@ Jonathan Allan Saya tidak mengerti bagaimana OR-ing akan membantu. Anda punya kode?
fireflame241
1
Karena Bselalu mengembalikan array yang dimulai dengan 1 , BUṪMṪ’×Ṡbisa menjadi ṪBL’. Juga, Anda tidak perlu , dan ḟ0menyimpan satu byte lebih ¹Ðf.
Dennis
5

Python 2 , 45 byte

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

Cobalah online!

Menyimpan banyak byte berkat Dennis! (Kepala untuk len(bin(...))-3bukannya math.frexp)

Terima kasih kepada @xnor karena menemukan bug, yang untungnya mudah diperbaiki!

Tuan Xcoder
sumber
Ini sepertinya memberikan jawaban yang salah seperti untuk x=3, saya kira karenaand/or sirkuit pendek salah ketika fungsi mengembalikan 0.
xnor
@ xnor Terima kasih telah memperhatikan itu! Sudah diperbaiki.
Tn. Xcoder
4

Perl 6 ,45 35 byte

Versi yang sangat ditingkatkan ini adalah milik @nwellnhof.

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

Cobalah online!

Ramillies
sumber
Anda cukup mencocokkan dengan :guntuk mendapatkan semua kecocokan. Dengan operator pertandingan-pintar, saya dapat menurunkannya hingga 40 byte:{sort(.base(2).flip~~m:g/1+/).tail.from}
nwellnhof
Dan hingga 35 byte:{.msb+1-(.base(2)~~m:g/1+/).max.to}
nwellnhof
@wellwell, terima kasih banyak. Saya entah bagaimana ketinggalan :gdan tidak tahu bagaimana saya bisa menggunakan kata keterangan dengan operator smartmatch. Juga .msbmetode ini sangat membantu di sini dan saya tidak tahu sebelumnya.
Ramillies
3

Python 2 , 89 78 byte

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

Cobalah online!

EDIT: Disimpan 11 byte berkat Tn. Xcoder.

Chas Brown
sumber
86 bytes
Mr. Xcoder
78 byte
Tn. Xcoder
@ Mr.Xcoder Saya juga memikirkan hal itu, meskipun pertanyaannya secara spesifik meminta untuk menulis suatu fungsi.
Jonathan Frech
@ JonathanFrech Saya tidak berpikir OP benar-benar berfungsi . Mungkin hanya istilah generik.
Tn. Xcoder
@ Mr.Xcoder Tolong jelaskan ini. Terima kasih,
lifebalance
3

05AB1E , 14 12 11 byte

bDγàŠrkrJgα

Cobalah online! atau menjalankan test case .

Penjelasan

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
sumber
3

J , 18 17 byte

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

Cobalah online!

Penjelasan

(#-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
mil
sumber
Sangat licin. Tidak yakin saya sepenuhnya memahami apa yang terjadi dengan konversi basis campuran. Mengapa menghitung jumlah yang berurutan di akhir string? Juga, jika basis yang ditentukan pada xangka dua semuanya 0 dan 1, apa artinya itu? Nomor basis 2 memiliki digit 0dan 1, jadi 1nomor dasar memiliki digit ... 0? lalu apa 1artinya dalam konteks itu? Dan apakah angka dasar 0selalu 0?
Jonah
@Jonah Ini lebih karena bagaimana konversi basis campuran diterapkan. x #. ypenghitungan pertama w =: */\. }. x , 1kemudian kembali+/ w * y
mil
jadi apakah Anda menganggap ini peretasan golf daripada penggunaan yang sah #., karena Anda lebih mengandalkan detail implementasi internal daripada api publik?
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)

Cobalah online!

Versi AC # dari jawaban @ Arnauld

Ucapan Terima Kasih

4 byte disimpan berkat Kevin Cruijssen.

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

Cobalah online!

+18 byte untuk using System.Linq;

Ucapan Terima Kasih

8 byte disimpan berkat Grzegorz Puławski.

Merosot

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

Cobalah online!

Sebuah non-Linq solusi , yang saya yakin dapat ditingkatkan, meskipun tidak ada yang langsung terlihat.

Merosot

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
sumber
1
Anda dapat menyimpan 8 byte dengan rmemasukkan jawaban pertama: tio.run/##dY9RS8MwFIWfza/…
Grzegorz Puławski
Anda dapat menyimpan dua byte di port Arnauld Anda seperti ini:T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
Kevin Cruijssen
1
Atau bahkan dua byte lagi yang disimpan ( 60 byte ):T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Kevin Cruijssen
2

Sekam , 12 byte

→S§-€¤≠Lo▲gḋ

Cobalah online!

Penjelasan

                 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.Piz
sumber
2

Jelly ,  14 13 12  11 byte

Bµṣ0Ṫ$ƤMḢạL

Tautan monadik yang mengambil dan mengembalikan bilangan bulat non-negatif.

Cobalah online! atau lihat test-suite .

Bagaimana?

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
sumber
Saya punya solusi serupa tetapi digunakan ŒrṪPpada awalan sebagai gantinya.
mil
2

Jelly , 19 byte

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

Cobalah online!

Terima kasih kepada Jonathan Allan karena telah menghemat  4  6 byte!

Saya telah bekerja terlalu banyak untuk meninggalkan ini, meskipun agak lama. Saya benar-benar ingin menambahkan solusi yang benar-benar mencari substring terpanjang1 dalam representasi biner ...

Penjelasan

BŒgḄṀB - Tautan pembantu monadik. Akan digunakan dengan Ç di tautan selanjutnya.

B - Representasi biner.
 Œg - Grup berjalan dengan elemen yang sama berturut-turut.
   Ḅ - Konversi dari biner ke integer.
    Ṁ - Nilai maksimum.
     B - Konversi dari integer ke biner.


BwÇɓÇL + ɓBL_ '- Tautan utama.

B - Representasi biner (dari input).
  Ç - Tautan terakhir sebagai monad. Mengambil integer input.
 w - Indeks sublist pertama.
   ɓ - Mulai rantai diad yang terpisah. Membalikkan argumen.
    Ç - Tautan terakhir sebagai monad.
     L - Panjang.
      + - Tambahan
       ɓ - Mulai rantai diad yang terpisah. Membalikkan argumen.
        B - Biner.
         L - Panjang.
          _ '- Kurangi dan tambahkan hasilnya (karena Jelly menggunakan pengindeksan 1).
              - Output tersirat.
Tuan Xcoder
sumber
Tautan pembantu Anda bisa berupa BŒgḄṀBsebaliknya
Jonathan Allan
@ Jonathan Allan Oh wow terima kasih!
Tn. Xcoder
Tautan utama Anda bisaBwÇɓÇL+ɓBL_‘
Jonathan Allan
@ JonathanAllan Wow, terima kasih lagi!
Tn. Xcoder
2

Kotlin , 77 byte

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

Yg diperindahkan

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

Uji

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
sumber
Saya tidak menguji tetapi berpikir ini bekerja dalam scala juga.
V. Courtois
2

Haskell , 101 98 96 75 byte

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

Cobalah online! Penggunaan: snd.maximum.(`zip`[0..]).c $ 142hasil 1.

Penjelasan:

  • cmengubah input menjadi biner sementara pada saat yang sama menghitung panjang goresan satu, mengumpulkan hasilnya dalam daftar. r<-c$div n 2rekursif menghitung sisa rdaftar ini, sambil sum[r!!0+1|mod n 2>0]:rmenambahkan panjang beruntun saat ini ke r. Pemahaman daftar memeriksa apakah mod n 2>0, yaitu apakah digit biner saat ini adalah satu, dan jika demikian, mengambil panjang dari garis sebelumnya (elemen pertama r) dan menambahkannya. Kalau tidak, pemahaman daftar kosong, dan sum[]menghasilkan 0. Sebagai input contoh, c 142menghasilkan daftar [0,3,2,1,0,0,0,1,0].

  • (`zip`[0..])menambahkan posisi ke setiap elemen dari daftar sebelumnya sebagai komponen kedua tupel. Sebagai contoh ini memberi [(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)].

  • maximummenemukan tupel maksimal leksikografis dalam daftar ini, yaitu panjang garis dianggap pertama karena mereka adalah komponen pertama, dan jika terjadi ikatan komponen kedua, yaitu indeks yang lebih besar, memutuskan. Ini menghasilkan (3,1)dalam contoh, dan sndmengembalikan komponen kedua dari tupel.

Laikoni
sumber
2

Python 2 atau 3 , 58 byte

import math
f=lambda x:x&x>>1and f(x&x>>1)or len(bin(x))-3

Cobalah online!

keseimbangan hidup
sumber
2

C (gcc) , 81 80 byte

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

Cobalah online!

C (gcc) , 43 byte

Versi AC dari jawaban @ Arnauld

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

Cobalah online!

Cleblanc
sumber
Kehilangan pengembalian n; atau mengembalikan k; pernyataan
RosLuP
Sarankan n<1?0:log2(n)alih-alih(k=log2(n))<0?0:k
ceilingcat
2

MS SQL Server, 437 426 407 398 byte

SQL Fiddle

Saya yakin bahwa saya bisa menghapus jeda baris, dll, tapi ini kompak seperti yang saya inginkan:

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

Ini versi yang lebih mudah dibaca:

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

Trik sebenarnya adalah sejauh yang saya bisa temukan, tidak ada fungsi SQL asli untuk mengubah angka dari desimal menjadi biner. Akibatnya, saya harus mengkodekan konversi ke biner secara manual, kemudian saya dapat membandingkannya sebagai string, satu karakter pada satu waktu sampai saya menemukan nomor yang tepat.

Saya yakin ada cara yang lebih baik untuk melakukan ini, tapi saya tidak melihat (n) jawaban SQL, jadi saya pikir saya akan membuangnya di sana.

phroureo
sumber
Jika Anda bisa bermain golf lebih banyak, silakan lakukan. Tetapi sebaliknya, ini luar biasa! Selamat datang di PPCG!
NoOneIsHere
@NoOneIsHere terima kasih! Saya menyadari bahwa saya dapat mempersingkat nama fungsi saya juga;)
phroureo
2

APL (Dyalog Unicode) , 22 karakter = 53 byte

Membutuhkan ⎕IO←0yang default pada banyak sistem.

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

Cobalah online!

 meminta input

 hasilkan itu (terpisah ¯1dari )

2⊥⍣¯1 konversikan ke basis-2, menggunakan posisi sebanyak yang diperlukan

b← simpan sebagai b(untuk b inary)

 membalikkan

(... ) tandai posisi awal sebagai berikut:

⊆⍨b partisi sendiri b(yaitu 1-coretan b)

 campur (buat daftar daftar menjadi matriks, diisi dengan nol)

∨⌿ pengurangan OR vertikal (menghasilkan goresan terpanjang)

d ndices posisi awal

 membalikkan

 pilih yang pertama (hasilkan nol jika tidak ada yang tersedia)

Adm
sumber
Anda kehilangan ∇ di catatan kaki pada tio
ngn
@ Ngn Benar Anda.
Adám
1

MATL , 15 byte

`tt2/kZ&t]xBnq&

Cobalah online!

Gunakan separuh dan ide AND. Yang kdiperlukan hanya untuk membuatnya berakhir1 - karena alasan tertentu, 1 DAN 0,5 mengembalikan 1, menyebabkan loop tak terbatas.

(solusi alternatif: BtnwY'tYswb*&X>)-dengan mengkonversi ke pengkodean biner dan run-length)

B. Mehta
sumber
1

Google Sheets, 94 byte

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

Tidak, tidak terlalu cantik. Sungguh menyenangkan bisa menyimpanDec2Bin(A1) sebagai variabel untuk referensi.

Poin utama: Seperti Excel, Dec2Binfungsi ini memiliki nilai input maksimal 511. Apa pun yang lebih besar dari itu akan mengembalikan kesalahan, seperti yang terlihat di bawah ini.

Hasil

Toast insinyur
sumber
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))
Zahiro Mor
sumber
104 byte! Alih-alih rev, gunakan Reduce(...,T,T)untuk menumpuk dari kanan (beralih x,ydalam definisi fungsi). Kemudian gunakan 1+max(z)-which.max(z)karena hasilnya agak berbeda. Gunakan "if"daripada "ifelse"karena kita tidak perlu vektorisasi; aaand jika Anda menggunakan any(z)alih-alih !sum(z)Anda menjatuhkan byte.
Giuseppe
Saya pikir kita harus bisa mendapatkan ini hingga kurang dari 100 byte.
Giuseppe
@giuseppe Saya merasa agak curang karena berada di sini sebelum Anda! Akan melakukan kali tnx banyak!
Zahiro Mor
Tapi pendekatan yang bagus bukan?
Zahiro Mor
1
Oh, jangan khawatir, saya melihat ini sebelumnya tetapi tidak merasa ingin menjawabnya karena R sangat buruk dalam operasi bit ... Ya, kerja bagus, Anda mendapatkan +1 saya
Giuseppe
1

Excel VBA, 54 44 Bytes

-10 Bytes berkat @EngineerToast

Fungsi jendela langsung VBE anonim yang mengambil input dari jarak [A1]dan keluaran ke jendela langsung VBE

?Instr(1,StrReverse([Dec2Bin(A1)]),1)+[A1>0]
Taylor Scott
sumber
1
Selain pengawasan yang C1masih ada di sana alih-alih A1, saya pikir Anda dapat menampilkan Instrhasilnya secara langsung dengan sedikit memutar untuk koreksi input nol: ?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0)(46 byte). Benar = -1 karena ... VBA.
Engineer Toast
@ EngineerToast - Manis! Saya seharusnya melihat itu; Saya bisa menjatuhkannya 2 byte dengan membawa >0ke [A1]notasi
Taylor Scott
0

R, 66 Bytes

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

Penjelasan:

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
sumber
1
Ini mengembalikan panjang garis terpanjang, bukan posisinya. Periksa terhadap kasus uji dan spesifikasi di bagian atas.
user2390246
Saya akan mengubah downvote saya menjadi upvote setelah jawaban ini diperbaiki. Juga, perhatikan bahwa Anda dapat menggunakan a$lbukannya a[[1]]dan a$vbukannya a[[2]]untuk menyimpan beberapa byte :), dan >0bukannya ==1.
Giuseppe
0

Javascript, 54 karakter

f=i=>i.toString(2).split(0).sort().reverse()[0].length
  • i.toString(2) mendapat string biner untuk integer.
  • The .split(0)mendapat masing-masing orang bagian berurutan dalam elemen array.
  • .sort().reverse() memberi kita nilai tertinggi sebagai yang pertama.
  • The [0].lengthmemberi kita panjang yang nilai pertama.
nl-x
sumber
the starting position of number of largest consecutive 1's
L3viathan
0

Perl 5, 45 + 1 (-p)

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

Jika Anda menulis ini di baris perintah sebagian besar shell, Anda mungkin harus mengetik ini sebagai:

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

Tarian kutipan di akhir hanya untuk mendapatkan perl melihat a ', yang seharusnya dikonsumsi oleh shell.


sumber
0

Retina , 52 43 byte

Konversikan ke biner, lalu ganti dengan panjang dari apa yang mengikuti string terbesar.

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

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

.

Coba online - semua test case

Disimpan 9 byte berkat Martin.

mbomb007
sumber
Anda dapat menggunakan $+untuk ${1}. Tetapi Anda dapat menyimpan lebih banyak lagi dengan mengganti tahap terakhir dengan sekelompok tahapan seperti ini: tio.run/##K0otycxL/K/…
Martin Ender
@MartinEnder Ok. Itu ${1}disalin dari tutorial Anda di Github.
mbomb007