Tính chuỗi số 1 dài nhất trong giá trị nhị phân của số nguyên


32

Mục tiêu

Cho một số nguyên không âm, tạo một hàm trả về vị trí bắt đầu của số 1 liên tiếp lớn nhất trong giá trị nhị phân của số nguyên đó.

Khi được cung cấp một đầu vào 0, trả lại 0.

Nếu số có nhiều vệt có độ dài bằng nhau, bạn phải trả về vị trí của vệt cuối cùng.

Đầu vào

Một số nguyên lớn hơn hoặc bằng 0.

Đầu ra

Một số nguyên được tính như dưới đây.

Quy tắc

  • Đây là mã golf, vì vậy mã ngắn nhất tính theo byte trong mỗi ngôn ngữ sẽ thắng.
  • Sơ hở tiêu chuẩn bị cấm.

Ví dụ và trường hợp thử nghiệm

ví dụ 1

  • Hàm của bạn được truyền số nguyên 142
  • 142 bằng 10001110 trong nhị phân
  • Chuỗi dài nhất là "111" (một chuỗi ba)
  • Chuỗi bắt đầu ở vị trí 2 ^ 1
  • Hàm của bạn trả về 1 là kết quả

Ví dụ 2

  • Hàm của bạn được truyền số nguyên 48
  • 48 bằng 110000 trong nhị phân
  • Chuỗi dài nhất là "11" (một vệt hai)
  • Chuỗi bắt đầu ở vị trí 2 ^ 4
  • Kết quả là hàm của bạn trả về 4

Ví dụ 3

  • Hàm của bạn được truyền số nguyên 750
  • 750 bằng 1011101110 ở dạng nhị phân
  • Chuỗi dài nhất là "111" (một chuỗi ba)
  • Vì có hai vệt có độ dài bằng nhau, chúng ta trả lại vệt sau.
  • Chuỗi sau bắt đầu ở vị trí 2 ^ 5
  • Kết quả là hàm của bạn trả về 5

1
Bạn cần một tiêu chí chiến thắng, như code-golf
Okx

@Okx Nó đã được đề cập trong chính cơ thể nên tôi đã thêm thẻ.
hoàn toàn là

Hãy chắc chắn rằng mọi người kiểm tra 0. Đó là một trường hợp thử nghiệm quan trọng.
mbomb007

2
Thay vì "vệt cuối" hoặc "vệt mới nhất", tôi đề nghị "vệt có giá trị lớn nhất".
aschepler

@Okx Tại sao một tiêu chí chiến thắng là cần thiết? Tại sao nó không thể đơn giản là một câu đố?
corsiKa

Câu trả lời:


21

Thạch , 10 8 byte

Ba\ÐƤṀċ¬

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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.

Xin chúc mừng!
Defacto

24

JavaScript (ES6), 41 40 36 34 byte

Đã lưu 4 byte nhờ @ThePirateBay

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

Các trường hợp thử nghiệm

Làm sao?

Trường hợp chung x> 0

Chúng tôi đệ quy VÀ đầu vào x với x / 2 làm giảm dần các mẫu của các bit được đặt liên tiếp cho đến khi chỉ còn lại bit ngoài cùng bên phải của chuỗi. Chúng tôi giữ một bản sao của giá trị khác không cuối cùng và xác định vị trí của bit quan trọng nhất của nó bằng cách làm tròn sàn logarit cơ sở 2 của nó.

Dưới đây là các bước chúng tôi thực hiện cho x = 750 ( 1011101110 ở dạng nhị phân).

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

Trường hợp cạnh x = 0

Trường hợp đặc biệt x = 0ngay lập tức dẫn đến Math.log2(0) | 0. Logarit của các 0ước lượng -Infinityvà nhị phân bit OR buộc một sự ép buộc thành một số nguyên 32 bit. Để tuân thủ các đặc điểm kỹ thuật của hoạt động trừu tượng ToInt32 , điều này mang lại sự mong đợi 0:

Nếu sốNaN , +0 , -0 , + ∞ , hoặc -∞ , trở về 0


Lỗi này cho đầu vào 0, là một phần của phạm vi đầu vào.
Justin Mariner

@JustinMariner Đã sửa.
Arnauld

Những gì về Math.log2(k)|0thay vì 31-Math.clz32(k)? Hay tôi đang thiếu một cái gì đó?

@ThePirateBay Math.log2(k)|0thực sự vừa ngắn hơn vừa đơn giản hơn cho trường hợp đặc biệt x=0. Cảm ơn. :)
Arnauld

1
Thuật toán rất đẹp, và giải thích tốt. Tôi đã thực hiện nó trong 14 byte mã máy x86 .
Peter Cordes

12

mã máy x86, 14 byte

Sử dụng thuật toán của @ Arnauldx &= x>>1 và lấy vị trí bit được đặt cao nhất trong bước trước khi xtrở thành 0.

Có thể gọi từ C / C ++ với chữ ký unsigned longest_set(unsigned edi);trong Hệ thống V ABI x86-64. Các byte mã máy tương tự sẽ giải mã theo cùng một cách trong chế độ 32 bit, nhưng các quy ước gọi 32 bit tiêu chuẩn không đặt đối số đầu tiên vào edi. (Thay đổi thanh ghi đầu vào thành ecxhoặc edxcho Windows _fastcall/ _vectorcallhoặc gcc -mregparmcó thể được thực hiện mà không vi phạm bất cứ điều gì.)

   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

BSRHướng dẫn của x86 (Bit Scan Reverse) là hoàn hảo cho việc này, cung cấp cho chúng tôi chỉ số bit trực tiếp, thay vì đếm các số 0 đứng đầu. ( bsrKhông trực tiếp sản xuất 0 cho input = 0 như 32-lzcnt(x)sẽ, nhưng chúng tôi cần BSR = 31 lzcnt cho phi zero-đầu vào, vì vậy lzcntthậm chí sẽ không tiết kiệm hướng dẫn, chúng ta hãy đếm byte một mình. Zeroing eax trước khi công trình vòng lặp vì bsr' hành vi bán chính thức của việc rời khỏi đích không được sửa đổi khi đầu vào bằng không.)

Điều này thậm chí sẽ ngắn hơn nếu chúng ta có thể trả lại vị trí MSB của lần chạy dài nhất. Trong trường hợp đó, lea ecx, [rdi+rdi](3 byte) sẽ sao chép + dịch chuyển sang trái thay vì mov+ shr(4 byte).

Xem liên kết TIO này cho một người gọi asm màexit(longest_set(argc-1));

Kiểm tra với một vòng lặp 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

1
Tốt đẹp! Một lưu ý cho những người (như tôi) quen thuộc hơn với các phương ngữ lắp ráp khác: ký hiệu x86 BSR là viết tắt của "Bit Scan Reverse", không phải "Branch to SubRoutine".
Arnauld

@Arnauld: điểm tốt, được chỉnh sửa để giải mã ghi nhớ cũng như có một liên kết đến mục hướng dẫn tham khảo nội bộ.
Peter Cordes

5

Thạch , 19 17 11 byte

HÐĿ&\ḟ0ṪBL’

Hãy thử trực tuyến!

-6 (!) Byte nhờ các quan sát sắc sảo của @ Dennis

Làm thế nào nó hoạt động

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

Lỗi cho 0, đó là trong phạm vi đầu vào.
Ông Xcoder

@ Mr.Xcoder Cố định
fireflame241

Bạn có thể lưu một byte để sửa lỗi vớiȯ-µ...
Jonathan Allan

@Jonathan ALLan Tôi không hiểu OR-ing sẽ giúp như thế nào. Bạn có mã không?
fireflame241

1
Bluôn trả về một mảng bắt đầu bằng 1 , BUṪMṪ’×Ṡcó thể trở thành ṪBL’. Ngoài ra, bạn không cần ḟ0lưu một byte qua ¹Ðf.
Dennis

5

Python 2 , 45 byte

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

Hãy thử trực tuyến!

Đã lưu rất nhiều byte nhờ Dennis! (Những người đứng đầu len(bin(...))-3thay vì math.frexp)

Cảm ơn @xnor vì đã tìm ra một lỗi, rất may là có thể dễ dàng sửa chữa!


Điều này dường như đưa ra câu trả lời sai như x=3, tôi nghĩ vì and/ormạch ngắn khi hàm trả về 0.
xnor

@xnor Cảm ơn bạn đã chú ý điều đó! Nó đã được sửa.
Ông Xcoder

4

Perl 6 ,45 35 byte

Phiên bản cải tiến cao này là lịch sự của @nwellnhof.

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

Hãy thử trực tuyến!


Bạn chỉ có thể kết hợp với :gđể có được tất cả các trận đấu. Với toán tử kết hợp thông minh, tôi có thể đánh gôn xuống tới 40 byte:{sort(.base(2).flip~~m:g/1+/).tail.from}
nwellnhof


@nwellnhof, cảm ơn bạn rất nhiều. Bằng cách nào đó tôi đã bỏ lỡ :gvà không hiểu làm thế nào tôi có thể sử dụng trạng từ với toán tử smartmatch. Ngoài ra .msbphương pháp này khá hữu ích ở đây và tôi không biết về nó trước đây.
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

Hãy thử trực tuyến!

EDIT: Đã lưu 11 byte nhờ ông Xcoder.




@ Mr.Xcoder Tôi cũng nghĩ về điều đó, mặc dù câu hỏi đặc biệt yêu cầu viết một hàm.
Jonathan Frech

@JonathanFrech Tôi không nghĩ OP thực sự có nghĩa là chức năng . Có lẽ chỉ là một thuật ngữ chung chung.
Ông Xcoder

@ Mr.Xcoder Hãy giải thích điều này. Cảm ơn,
cuộc sống

3

05AB1E , 14 12 11 byte

bDγàŠrkrJgα

Hãy thử trực tuyến! hoặc chạy thử trường hợp .

Giải trình

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 17 byte

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

Hãy thử trực tuyến!

Giải trình

(#-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

Rất lắt léo. Không chắc chắn tôi hoàn toàn hiểu những gì đang xảy ra với chuyển đổi cơ sở hỗn hợp mặc dù. Tại sao nó đếm số lượng liên tiếp ở cuối chuỗi? Ngoài ra, nếu các căn cứ được chỉ định trên xđê là tất cả 0 và 1, điều đó có nghĩa là gì? Một số cơ sở 2 có các chữ số 01, vì vậy một 1số cơ sở có các chữ số ... 0? Vậy thì 1có nghĩa gì trong bối cảnh đó? Và một 0số cơ sở chỉ luôn luôn 0?
Giô-na

@Jonah Đó là do cách chuyển đổi cơ sở hỗn hợp được thực hiện. x #. yTính toán đầu tiên w =: */\. }. x , 1sau đó trả+/ w * y
dặm

Vì vậy, bạn sẽ coi đây là một hack golf chứ không phải là sử dụng hợp pháp #., vì bạn đang dựa vào các chi tiết thực hiện nội bộ hơn là api công cộng?
Giô-na

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)

Hãy thử trực tuyến!

Phiên bản AC # của câu trả lời của @ Arnauld

Lời cảm ơn

4 byte được lưu nhờ 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;}

Hãy thử trực tuyến!

+18 byte cho using System.Linq;

Lời cảm ơn

8 byte được lưu nhờ Grzegorz Puławski.

Bị khử

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

Hãy thử trực tuyến!

Một Linqgiải pháp không phải là giải pháp mà tôi chắc chắn có thể được cải thiện, mặc dù không có gì rõ ràng ngay lập tức.

Bị khử

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
Bạn có thể tiết kiệm 8 byte bằng cách bỏ rqua câu trả lời đầu tiên: tio.run/##dY9RS8MwFIWfza/ mẹo
Grzegorz Puławski

Bạn có thể lưu hai byte trong cổng Arnauld của mình như thế này:T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
Kevin Cruijssen

1
Hoặc thậm chí thêm hai byte được lưu ( 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

Husk , 12 byte

→S§-€¤≠Lo▲gḋ

Hãy thử trực tuyến!

Giải trình

                 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

Thạch ,  14 13 12  11 byte

Bµṣ0Ṫ$ƤMḢạL

Một liên kết đơn lấy và trả về số nguyên không âm.

Hãy thử trực tuyến! hoặc xem bộ thử nghiệm .

Làm sao?

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

Tôi đã có một giải pháp tương tự nhưng ŒrṪPthay vào đó được sử dụng trên các tiền tố.
dặm

2

Thạch , 19 byte

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

Hãy thử trực tuyến!

Cảm ơn Jonathan Allan vì đã tiết kiệm  4  6 byte!

Tôi đã làm việc quá nhiều để từ bỏ điều này, mặc dù nó khá dài. Tôi thực sự muốn thêm một giải pháp tìm kiếm chuỗi con dài nhất 1trong biểu diễn nhị phân ...

Giải trình

BŒgḄṀB - Liên kết trợ giúp đơn nguyên. Sẽ được sử dụng với trong liên kết tiếp theo.

B - Đại diện nhị phân.
 G - Nhóm chạy các phần tử bằng nhau liên tiếp.
   Ḅ - Chuyển đổi từ nhị phân sang số nguyên.
    Ṁ - Giá trị tối đa.
     B - Chuyển đổi từ số nguyên sang nhị phân.


BwÇɓÇL + BL_ '- Liên kết chính.

B - Biểu diễn nhị phân (của đầu vào).
  - Liên kết cuối cùng là một đơn nguyên. Lấy số nguyên đầu vào.
 w - Chỉ mục danh sách con đầu tiên.
   - Bắt đầu một chuỗi dyadic riêng biệt. Đảo ngược các đối số.
    - Liên kết cuối cùng là một đơn nguyên.
     L - Chiều dài.
      + - Bổ sung
       - Bắt đầu một chuỗi dyadic riêng biệt. Đảo ngược các đối số.
        B - Nhị phân.
         L - Chiều dài.
          _ '- Trừ và tăng kết quả (vì Jelly sử dụng lập chỉ mục 1).
              - Ngẫu nhiên đầu ra.

BŒgḄṀBThay vào đó, liên kết người trợ giúp của bạn có thể được thay thế
Jonathan Allan

@Jonathan ALLan Oh wow cảm ơn!
Ông Xcoder

Liên kết chính của bạn có thể làBwÇɓÇL+ɓBL_‘
Jonathan Allan

@Jonathan ALLan Wow, cảm ơn lần nữa!
Ông Xcoder

2

Kotlin , 77 byte

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

Làm đẹp

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

Kiểm tra

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}")
}

Tôi đã không kiểm tra nhưng nghĩ rằng điều này cũng hoạt động trong scala.
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

Hãy thử trực tuyến! Cách sử dụng: snd.maximum.(`zip`[0..]).c $ 142sản lượng 1.

Giải trình:

  • cchuyển đổi đầu vào thành nhị phân đồng thời đếm chiều dài các vệt của một, thu thập kết quả trong một danh sách. r<-c$div n 2đệ quy tính toán phần còn lại rcủa danh sách này, đồng thời sum[r!!0+1|mod n 2>0]:rthêm độ dài hiện tại của vệt vào r. Việc hiểu danh sách kiểm tra xem mod n 2>0, đó là liệu chữ số nhị phân hiện tại có phải là một hay không, và nếu vậy, sẽ lấy độ dài của vệt trước đó (phần tử đầu tiên của r) và thêm một. Nếu không, sự hiểu biết danh sách là trống rỗng, và sum[]mang lại 0. Đối với đầu vào ví dụ, c 142mang lại danh sách [0,3,2,1,0,0,0,1,0].

  • (`zip`[0..])thêm vị trí cho từng thành phần của danh sách trước làm thành phần thứ hai của bộ dữ liệu. Ví dụ này cho [(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)].

  • maximumtìm thấy bộ dữ liệu tối đa từ vựng trong danh sách này, đó là độ dài vệt được xem xét đầu tiên vì chúng là thành phần đầu tiên và trong trường hợp liên kết thành phần thứ hai, cụ thể là chỉ số lớn hơn, sẽ quyết định. Điều này mang lại (3,1)trong ví dụ và sndtrả về thành phần thứ hai của bộ dữ liệu.




2

Máy chủ MS SQL, 437 426 407 398 byte

Câu đố SQL

Tôi chắc chắn rằng tôi có thể loại bỏ ngắt dòng, v.v., nhưng điều này nhỏ gọn như tôi sẵn sàng thực hiện:

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

Đây là một phiên bản dễ đọc hơn:

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

Thủ thuật thực sự là theo như tôi có thể tìm thấy, không có chức năng SQL gốc để chuyển đổi một số từ thập phân sang nhị phân. Kết quả là, tôi phải mã hóa chuyển đổi thành nhị phân theo cách thủ công, sau đó tôi có thể so sánh đó là một chuỗi, một ký tự tại một thời điểm cho đến khi tôi tìm thấy đúng số.

Tôi chắc chắn có một cách tốt hơn để làm điều này, nhưng tôi đã không thấy câu trả lời (n) SQL, vì vậy tôi nghĩ rằng tôi sẽ ném nó ra khỏi đó.


Nếu bạn có thể chơi nó nhiều hơn, xin vui lòng làm như vậy. Nhưng nếu không, điều này là tuyệt vời! Chào mừng đến với PPCG!
NoOneIsHãy

@Không có cảm ơn! Tôi nhận ra rằng tôi cũng có thể rút ngắn tên hàm của mình;)
phroureo

2

APL (Dyalog Unicode) , 22 ký tự = 53 byte

Yêu cầu ⎕IO←0mặc định trên nhiều hệ thống.

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

Hãy thử trực tuyến!

 nhắc nhở cho đầu vào

 mang lại (tách ¯1từ )

2⊥⍣¯1 chuyển đổi sang cơ sở 2, sử dụng càng nhiều vị trí cần thiết

b← lưu trữ dưới dạng b(đối với b inary)

 đảo ngược

(... ) đánh dấu các vị trí bắt đầu của những điều sau đây trong đó:

⊆⍨b tự phân vùng b(tức là các vệt 1 b)

 trộn (lập danh sách các danh sách thành ma trận, đệm với số không)

∨⌿ giảm OR dọc (mang lại vệt dài nhất)

thông tin về vị trí bắt đầu

 đảo ngược

 chọn cái đầu tiên (mang lại số 0 nếu không có sẵn)


bạn đang thiếu một trong phần chân trang trên tio
ngn

@ngn Đúng rồi bạn.
Adám

1

MATL , 15 byte

`tt2/kZ&t]xBnq&

Hãy thử trực tuyến!

Sử dụng một nửa và ý tưởng AND. Điều knày chỉ cần thiết để làm cho nó chấm dứt 1- vì một số lý do, 1 VÀ 0,5 trả về 1, gây ra một vòng lặp vô hạn.

(giải pháp thay thế: BtnwY'tYswb*&X>)-bằng cách chuyển đổi sang mã hóa nhị phân và độ dài chạy)


1

Google Sheets, 94 byte

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

Không, nó không đẹp lắm. Thật tuyệt khi có thể lưu trữ Dec2Bin(A1)dưới dạng một biến để tham khảo.

Điểm chính: Giống như Excel, Dec2Binhàm có giá trị đầu vào tối đa là 511. Bất cứ điều gì lớn hơn sẽ trả về một lỗi, như được thấy dưới đây.

Các kết quả


1

R, 117 byte

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 byte! Thay vì revsử dụng Reduce(...,T,T)để tích lũy từ bên phải (chuyển đổi x,ytrong định nghĩa hàm). Sau đó sử dụng 1+max(z)-which.max(z)vì kết quả là hơi khác nhau. Sử dụng "if"thay vì "ifelse"vì chúng ta không cần vector hóa; aaand nếu bạn sử dụng any(z)thay vì !sum(z)bạn thả một byte.
Giuseppe

Tôi nghĩ rằng chúng ta sẽ có thể có được điều này đến dưới 100 byte.
Giuseppe

@giuseppe Tôi cảm thấy có phần gian lận vì đã ở đây trước bạn! Sẽ làm lần tnx một bó!
Zahiro Mor

Nhưng một cách tiếp cận tốt đẹp không?
Zahiro Mor

1
Ồ, đừng lo lắng, tôi đã thấy điều này sớm hơn nhưng không cảm thấy muốn trả lời vì R rất tệ trong các hoạt động bit ... Vâng, làm tốt lắm, bạn đã có +1 của mình
Giuseppe

1

VBA Excel, 54 44 byte

-10 byte nhờ @EngineerToast

Chức năng cửa sổ tức thời VBE ẩn danh nhận đầu vào từ phạm vi [A1]và đầu ra cho cửa sổ ngay lập tức VBE

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

1
Bên cạnh việc giám sát C1vẫn còn ở đó thay vào đó A1, tôi nghĩ bạn có thể xuất Instrkết quả trực tiếp với một chút xoắn để điều chỉnh đầu vào bằng 0: ?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0)(46 byte). Đúng = -1 vì ... VBA.
Kỹ sư Toast

@EngineerToast - Ngọt ngào! Tôi nên thấy điều đó; Tôi đã có thể thả nó xuống 2 byte bằng cách đưa >0vào các [A1]ký hiệu
Taylor Scott



0

R, 66 byte

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

Giải trình:

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
Điều này trả về độ dài của vệt dài nhất, không phải vị trí của nó. Kiểm tra đối với các trường hợp thử nghiệm và thông số kỹ thuật ở trên cùng.
dùng2390246

Tôi sẽ thay đổi downvote của mình thành upvote sau khi câu trả lời này được sửa. Ngoài ra, lưu ý rằng bạn có thể sử dụng a$lthay vì a[[1]]a$vthay vì a[[2]]để lưu một số byte :), cũng như >0thay vì ==1.
Giuseppe


0

Javascript, 54 ký tự

f=i=>i.toString(2).split(0).sort().reverse()[0].length
  • i.toString(2) được chuỗi nhị phân cho số nguyên.
  • Các phần .split(0)được nhận từng phần trong một phần tử mảng.
  • .sort().reverse() được chúng tôi giá trị cao nhất như đầu tiên.
  • Việc [0].lengthcho chúng ta độ dài của giá trị đầu tiên đó.

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

0

Perl 5, 45 + 1 (-p)

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

Nếu bạn viết nó ra trên dòng lệnh của hầu hết các shell, bạn có thể phải gõ nó như sau:

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

Vũ điệu của các trích dẫn ở cuối chỉ là để perl thấy a ', nếu không sẽ bị vỏ.


0

Võng mạc , 52 43 byte

Chuyển đổi thành nhị phân, sau đó thay thế bằng độ dài của chuỗi sau chuỗi lớn nhất.

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

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

.

Dùng thử trực tuyến - tất cả các trường hợp thử nghiệm

Lưu được 9 byte nhờ Martin.


Bạn có thể sử dụng $+cho ${1}. Nhưng bạn có thể tiết kiệm nhiều hơn bằng cách thay thế giai đoạn cuối bằng một loạt các giai đoạn như thế này: tio.run/##K0otycxL/K/ Kẻ
Martin Ender

@MartinEnder Ok. Đã ${1}được sao chép từ hướng dẫn của bạn trên Github.
mbomb007
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.