Bit chạy rundown


43

Cho một số nguyên n > 0, xuất độ dài của chuỗi liền kề dài nhất 0hoặc 1trong biểu diễn nhị phân của nó.

Ví dụ

  • 6được viết 110dưới dạng nhị phân; trình tự dài nhất là 11, vì vậy chúng ta nên quay trở lại2
  • 16100004
  • 89311011111015
  • 13373711010001101000000110116
  • 111
  • 99655461001100000001111111010107


Chúng ta có thể giả sử bất kỳ ràng buộc nào về kích thước của số nguyên như 32 bit hoặc 64 bit không?
xnor

@xnor vâng, bạn có thể giả sử int là tối đa 32 bit
Arnaud

Câu trả lời:


30

Python 2 , 46 45 byte

f=lambda n,k=1:`k`in bin(n^n/2)and-~f(n,k*10)

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

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

Bằng XORing nn / 2 (chia cho 2 về cơ bản là cắt bỏ bit cuối cùng), chúng ta nhận được một số nguyên m mới có các bit không đặt cho biết các bit liền kề khớp với n .

Ví dụ: nếu n = 1337371 , chúng ta có như sau.

n    = 1337371 = 101000110100000011011₂
n/2  =  668685 =  10100011010000001101₂
m    = 1989654 = 111100101110000010110₂

Điều này làm giảm nhiệm vụ tìm kiếm số 0 dài nhất. Vì biểu diễn nhị phân của một số nguyên dương luôn bắt đầu bằng 1 , chúng tôi sẽ cố gắng tìm chuỗi 10 * chữ số dài nhất xuất hiện trong biểu diễn nhị phân của m . Điều này có thể được thực hiện đệ quy.

Khởi tạo k1 . Mỗi lần f được thực thi, trước tiên chúng ta kiểm tra xem biểu diễn thập phân của k xuất hiện trong biểu diễn nhị phân của m . Nếu có, chúng ta nhân k với 10 và gọi lại f . Nếu không, mã bên phải andkhông được thực thi và chúng tôi trả về Sai .

Để làm điều này, trước tiên chúng tôi tính toán bin(k)[3:]. Trong ví dụ của chúng tôi, bin(k)trả về '0b111100101110000010110'0b1ở đầu được loại bỏ bằng [3:].

Bây giờ, -~trước cuộc gọi đệ quy tăng Sai / 0 một lần cho mỗi lần f được gọi đệ quy. Khi 10 {j} ( 1 theo sau là j lặp lại 0 ) không xuất hiện trong biểu diễn nhị phân của k , chuỗi số 0 dài nhất trong k có độ dài j - 1 . Vì j - 1 số 0 liên tiếp trong k chỉ ra j khớp với các bit liền kề trong n , kết quả mong muốn là j , đó là những gì chúng ta thu được bằng cách tăng Sai / 0tổng cộng j lần.


2
Điều này thực sự thông minh!
CraigR8806

1
Wow, thật thông minh. Không bao giờ có thể nghĩ về nó.
HyperNeutrino

Thủ thuật hay với sức mạnh của 10, nhưng chúng không trở nên dài với chữ L?
xnor

@xnor Cuối cùng, nhưng đó chỉ là giới hạn loại dữ liệu. Các câu trả lời C, JavaScript và PHP cũng bị như vậy.
Dennis

Điều này sẽ nghiêm trọng không thể nhầm lẫn nếu được sử dụng trong sản xuất. Trong ngắn hạn (ghehe) golf đạt được, lỗ trong một :)
JAK

17

Python 2, 46 byte

f=lambda n,r=1:max(r,n and f(n/2,1+~-n/2%2*r))

Dùng thử trực tuyến

Trích xuất các chữ số nhị phân từ nngược lại bằng cách liên tục lấy n/2n%2. Theo dõi độ dài của lần chạy hiện tại rcủa các chữ số bằng cách đặt lại về 0 nếu hai chữ số cuối không bằng nhau, sau đó thêm 1.

Biểu thức ~-n/2%2là một chỉ báo cho biết hai chữ số cuối có bằng nhau hay không, tức nlà 0 hoặc 3 modulo 4. Kiểm tra hai chữ số cuối cùng với nhau hóa ra rút ngắn hơn so với việc nhớ chữ số trước đó.



9

Toán học, 38 byte

Max[Length/@Split[#~IntegerDigits~2]]&

hoặc là

Max[Tr/@(1^Split[#~IntegerDigits~2])]&

9

Python, 53 byte

import re;lambda g:max(map(len,re.findall('1+|0+',bin(g))))

Chức năng lambda ẩn danh.


9

Thạch , 6 byte

BŒgL€Ṁ

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

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

BŒgL€Ṁ  Main link. Argument: n

B       Binary; convert n to base 2.
 Œg     Group adjacent, identical elements.
   L€   Map length over the groups.
     Ṁ  Take the maximum.

9

Ruby, 41 40 byte

->b{("%b%b"%[b,~b]).scan(/1+/).max.size}

Tìm chuỗi dài nhất '1' trong b hoặc nghịch đảo của nó.

Nhờ manatwork để tiết kiệm 1 byte.


2
Không chắc chắn về các phiên bản khác, nhưng trong 2.3.1, không cần khoảng trống giữa các %b.
thao tác

Bạn đã đúng, số nhị phân âm bắt đầu bằng "..". Cảm ơn.
GB

7

JavaScript (ES6), 54 byte

f=(n,r=0,l=1,d=2)=>n?f(n>>1,d^n&1?1:++r,r>l?r:l,n&1):l

Một giải pháp đệ quy với nhiều thao tác bit. nlưu trữ đầu vào, rlưu trữ độ dài của lần chạy hiện tại, llưu trữ độ dài của lần chạy dài nhất và dlưu trữ chữ số trước đó.

Kiểm tra đoạn

f=(n,r=0,l=1,d=2)=>n?f(n>>1,d^n&1?1:++r,r>l?r:l,n&1):l

for(var i of [0,1,2,3,4,5,6,7,8,9,16,893,1337371]) console.log(`f(${i}): ${f(i)}`)


1
Cùng một ý tưởng, nhưng sử dụng nhiều thao tác bit hơn và khai thác chuyển đổi mặc định không xác định thành 0. Hãy thoải mái mượn:f=(x,b,n,m)=>x?f(x>>1,x&1,n=x&1^b||-~n,m>n?m:n):m
edc65

7

Ruby, 51 44 43 byte

Giải pháp chức năng.

@manatwork được làm bằng phép thuật

->s{('%b'%s).scan(/0+|1+/).map(&:size).max}

Điều này có kiểm tra các chữ số giống hệt nhau liên tiếp hoặc chỉ 0s liên tiếp không?
ngenisis

2
Kết quả không chính xác cho 893.
orlp

@orlp không còn nữa! : D
Mực giá trị

1
Tôi sẽ kết hợp các giải pháp 1 và 2 : ->s{s.to_s(2).scan(/0+|1+/).map(&:size).max}.
thao tác

6

Python 2, 57 byte

a=lambda n:n and max((n&-n|~n&-~n).bit_length()-1,a(n/2))

Một giải pháp đệ quy. Có thể có một dạng ngắn hơn cho phép thuật bit.


6

Perl, 43 byte

#!perl -p
\@a[$a+=$_-1+($_>>=1)&1||-$a]while$_;$_=@a

Đếm shebang là một, đầu vào được lấy từ stdin.

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


Shebang được tính là 0 byte.
Máy

@CalculatorFeline đồng thuận về meta#!perltính bằng 0, không #!perl -p.
primo

@CalculatorFeline: -pChi phí 1, với giả định rằng dòng lệnh Perl của bạn dù sao cũng sẽ có một đối số (ví dụ -ehoặc -M5.010), do đó bạn có thể trượt pvào chỉ sau một dấu gạch nối. Các #!perllà miễn phí (mặc dù không cần thiết).

Tốt để biết. .
Máy

5

Pip , 16 byte

Có vẻ như phải có một cách ngắn hơn để có được các chữ số tương tự ...

MX#*(TBa`1+|0+`)

Lấy đầu vào làm đối số dòng lệnh. Hãy thử trực tuyến!

Giải trình

     TBa          1st cmdline arg, To Binary
    (   `1+|0+`)  Find all matches of this regex
  #*              Map length operator to that list
MX                Get the maximum and autoprint it

5

Perl 6 , 36 byte

{(.base(2)~~m:g/1+|0+/)».chars.max}

Giải trình:

{                                 }   # a lambda
  .base(2)                            # convert the argument to base 2
          ~~m:g/     /                # regex match, with global matching turned on
                1+|0+                 # match one or more 1, or one or more 0
 (                    )».chars        # replace each match by its length
                              .max    # take the maximum number

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


4

Haskell, 79 ký tự

maximum.map length.group.i

Ở đâu

import Data.List
i 0=[]
i n=mod n 2:i(div n 2)

Hoặc trong phiên bản chưa được chỉnh sửa:

import Data.List
pcg :: Int -> Int
pcg = maximum . map length . group . intToBin

intToBin :: Int -> [Int]
intToBin 0 = []
intToBin n = n `mod` 2 : intToBin (n `div` 2)

Giải trình:

intToBinchuyển đổi một int thành một danh sách các chữ số nhị phân (lsb đầu tiên). groupcác nhóm tiếp giáp nhau, như vậy [1, 1, 0, 0, 0, 1]trở thành [[1, 1],[0, 0, 0],[1]]. maximum . map lengthtính toán cho mỗi danh sách bên trong chiều dài của nó và trả về độ dài dài nhất.

Chỉnh sửa: Cảm ơn @xnor và @Laikoni vì đã lưu byte


2
groupkhông phải trong Prelude theo mặc định, bạn cần phải làm gì import Data.Listđể sử dụng nó.
xnor

1
Lưu ý rằng bạn có thể sử dụng vệ sĩ thay cho let: i n|(q,r)<-n`quotRem`2=r:i q. Xem mẹo chơi gôn Haskell của chúng tôi . quotRemcó thể divMod. Tôi nghĩ bạn có thể sử dụng i 0=[]như trường hợp cơ sở.
xnor

1
Sử dụng divmodtrực tiếp thậm chí còn ngắn hơn : i n=mod n 2:i(div n 2).
Laikoni

3

Bình thường, 7 byte

heSr8.B

Đừng chạy mã hóa chiều dài trên chuỗi nhị phân, sau đó sắp xếp nó sao cho lần chạy dài nhất đến sau cùng, sau đó lấy phần tử đầu tiên (độ dài) của phần tử cuối cùng (lần chạy dài nhất) của danh sách.

Trong mã giả:

'  S     ' sorted(
'   r8   '   run_length_encode(
'     .BQ'     bin(input()) ))  \
'he      '   [-1][0]

3

J , 21 byte

[:>./#:#;.1~1,2~:/\#:

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

Giải trình

[:>./#:#;.1~1,2~:/\#:  Input: integer n
                   #:  Binary digits of n
              2   \    For each continuous subarray of 2 digits
               ~:/       Reduce it using not-equals
            1,         Prepend a 1 to those results
     #:                Binary digits of n
        ;.1~           Cut the binary digits at each location with a 1
       #                 Get the length of each cut
[:>./                  Reduce those lengths using maximum and return

3

MATLAB 71 byte

m=1;a=diff(int8(dec2bin(a)));while(any(a==0)),m=m+1;a=diff(a);end;m

Điều này chuyển đổi biến số nguyên 'a' thành mảng int8 nhị phân sau đó đếm số lần kết quả phải được phân biệt cho đến khi không có số 0 trong kết quả.

Tôi là người mới ở đây. Đây có phải là loại đầu vào và một lớp lót được cho phép bởi các quy tắc PCG không?


3
Chào mừng đến với PPCG! Theo mặc định, chỉ các chức năng hoặc chương trình đầy đủ (không phải đoạn mã) được chấp nhận. Trong trường hợp của bạn có nghĩa là bạn cần phải nhập avới a=input('');. Ngoài ra, một số lời khuyên chơi golf: ~athay vì a==0. Bạn có thực sự cần int8)?
Luis Mendo

3

Octave , 31 byte

@(n)max(runlength(+dec2bin(n)))

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

Giải trình

Đây là bản dịch câu trả lời MATL của tôi. Kế hoạch ban đầu của tôi là một cách tiếp cận khác, cụ thể là @(n)max(diff(find(diff([0 +dec2bin(n) 0])))). Nhưng hóa ra Octave có một runlengthchức năng (mà tôi vừa tìm ra). Theo mặc định, nó chỉ xuất ra mảng có độ dài chạy, do đó, kết quả mong muốn là maxmảng đó. Đầu ra của dec2bin, là một mảng char (chuỗi) có chứa '0''1', cần phải được chuyển đổi thành một mảng số bằng cách sử dụng +, bởi vì runlengthmong đợi đầu vào số.


3

Tiện ích Bash / Unix, 66 65 42 byte

Cảm ơn @DigitalTrauma vì những cải tiến đáng kể (23 byte!).

dc<<<`dc -e2o?p|fold -1|uniq -c|sort -n`rp

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


1
@DigitalTrauma Cảm ơn những cải tiến, đặc biệt là bao gồm cả nếp gấp, vốn không có trong kho vũ khí thông thường của tôi.
Spector Mitchell

3

Bash (+ coreutils, + GNU grep), 33, 32 byte

CHỈNH SỬA:

  • Trừ đi 1 byte (loại bỏ dấu ngoặc kép quanh biểu thức grep )

Chơi gôn

dc -e2o$1p|grep -Po 1+\|0+|wc -L

Giải thích

 #Convert to binary
 >dc -e2o893p
 1101111101

 #Place each continuous run of 1es or 0es on its own line
 >dc -e2o893p|grep -Po '1+|0+'
 11
 0
 11111
 0
 1

 #Output the length of the longest line
 >dc -e2o893p|grep -Po '1+|0+'|wc -L
 5

Dùng thử trực tuyến!


AFAIK, grep không phải là một phần của bash hay coreutils, mặc dù được duy trì và phân phối bởi chính nó . Không chắc chắn về dc, nhưng nó từng là một công cụ độc lập trong thế giới GNU. Phần duy nhất hình thành của coreutils là wc.
Moreaki

@Moreaki, grep là POSIX, vì vậy bất kỳ câu trả lời dựa trên vỏ nào cũng ngụ ý rằng nó đã có sẵn. dc không phải là POSIX nhưng là một phần tiêu chuẩn của hầu hết mọi hệ thống * Nix xung quanh, do đó, nó thường không được đề cập như một phụ thuộc riêng biệt.
zeppelin

Tôi cho rằng chúng tôi đang ở trên hai luồng suy nghĩ khác nhau ở đây: quan điểm của tôi không phải là grep có phải là POSIX hay không, quan điểm của tôi là tiêu đề của bạn gửi cho tôi chỉ ra rằng người ta sẽ cần bash + coreutils để giải pháp của bạn hoạt động, trong khi Điều này dường như không phải là trường hợp. Khi tôi đọc nó lần đầu tiên, thông tin này đã gây nhầm lẫn cho tôi. Nếu bạn thử giải pháp của mình trên vỏ bash vận chuyển macOS, nó sẽ không hoạt động; và nó không quan trọng nếu bạn cài đặt coreutils hay không; bạn cần GNU grep để làm cho nó hoạt động.
Moreaki

@Moreaki, vâng, tôi chỉ ngụ ý hệ thống GNU, khi tôi nói + coreutils, không phải lúc nào cũng như vậy. Tôi đã cập nhật tiêu đề để chính xác hơn.
zeppelin


2

C #, 106 byte

n=>{int l=1,o=0,p=0;foreach(var c in System.Convert.ToString(n,2)){o=c!=p?1:o+1;l=o>l?o:l;p=c;}return l;};

Phiên bản định dạng:

System.Func<int, int> f = n =>
{
    int l = 1, o = 0, p = 0;
    foreach (var c in System.Convert.ToString(n, 2))
    {
        o = c != p ? 1 : o + 1;

        l = o > l ? o : l;

        p = c;
    }

    return l;
};

Và một cách tiếp cận khác để truy cập chuỗi theo chỉ mục ở mức 118 byte, với khoảng trắng được xóa:

System.Func<int, int> f2 = n =>
{
    var s = System.Convert.ToString(n, 2);

    int l = 1, c = 1, i = 0;

    for (; i < s.Length - 1; )
    {
        c = s[i] == s[++i] ? c + 1 : 1;
        l = l < c ? c : l;
    }

    return l;
};

2

Javascript, 66 byte

x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.leng‌​th))

Nhờ manatwork cho mã.

Giải trình

x.toString(2)

Chuyển đổi số thành chuỗi nhị phân.

split(/(0+|1+)/g)

Tách mọi ký tự khác nhau (0 hoặc 1) (regex này ghi lại các khoảng trống nhưng chúng có thể bị bỏ qua)

map(y=>y.length)

Đối với mỗi phần tử của mảng, lấy chiều dài của nó và đặt nó vào mảng trả về.

...

Chuyển mảng thành danh sách các đối số ([1,2,3] -> 1,2,3)

Math.max()

Lấy số lượng lớn nhất trong số các đối số.


1
Bằng cách ghi có giải pháp Ruby của Value Ink cho cảm hứng, điều này có thể được chuyển thành . Hoặc cùng chiều dài : . x=>x.toString(2).split(/(0+|1+)/g).map(y=>y.length).sort().pop()x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.length))
thao tác

3
Tôi nghĩ rằng bạn có thể phải thêm một vị ngữ cho hàm sắp xếp sort((a,b)=>b-a). Theo mặc định, hàm sắp xếp đặt 10ở giữa 12.
Mama Fun Roll

Hoặc bạn có thể sử dụng Math.max, như đề xuất manatwork.
Mama Fun Roll

Wtf, nhưng chúng là những con số. Xin vui lòng.

2

Kỳ quan , 27 byte

max.map#len.mstr`0+|1+`g.bn

Sử dụng:

(max.map#len.mstr`0+|1+`g.bn)123

Chuyển đổi thành nhị phân, khớp từng chuỗi 0 và 1, lấy độ dài của mỗi trận đấu và lấy mức tối đa.


Điều này có chuyển đổi đầu vào thành nhị phân không?
Laikoni

oooooh tôi đã bỏ lỡ phần đó. Khắc phục nhanh: P
Mama Fun Roll

2

Mẻ, 102 byte

@set/a"n=%1/2,d=%1%%2,r=1+(%3+0)*!(0%2^d),l=%4-(%4-r>>5)
@if not %n%==0 %0 %n% %d% %r% %l%
@echo %l%

Câu trả lời của cảng @ edc65. %2.. %4sẽ trống trong cuộc gọi đầu tiên, vì vậy tôi phải viết các biểu thức theo cách mà chúng vẫn sẽ hoạt động. Trường hợp chung nhất là %3tôi phải viết như (%3+0). %2là dễ dàng hơn, vì nó chỉ có thể 0hoặc 1, giống nhau trong bát phân, vì vậy 0%2làm việc ở đây. %4Hóa ra còn dễ hơn nữa, vì tôi chỉ cần trừ nó ra. (%4-r>>5)được sử dụng để so sánh lvới rnhư hàng loạt của set/akhông có toán tử so sánh.


2

APL Dyalog , 22 byte

Chức năng ẩn danh

⌈/∘(≢¨⊢⊂⍨1,2≠/⊢)2⊥⍣¯1

⌈/∘(... Tối đa kết quả của khóa đào tạo hàm ẩn danh sau đây ...

≢¨  kiểm đếm của mỗi

⊢⊂⍨ phân vùng của đối số, trong đó phân vùng được xác định bởi các đối số trong

1, một dự kiến

2≠/ cặp đôi không bằng nhau

 tranh luận

) áp dụng cho

2⊥⍣¯1 từ cơ sở-2 áp dụng tiêu cực một lần (nghĩa là đến cơ sở-2, một lần) cho

 tranh luận

Dùng thử trực tuyến!


2

Japt, 15 byte

2o!q¢ c ml n gJ

Kiểm tra nó trực tuyến! hoặc Xác minh tất cả các trường hợp thử nghiệm cùng một lúc .

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

                 // Implicit: U = input integer, J = -1
2o               // Create the range [0...2), or [0,1].
  ! ¢            // Map each item Z in this range to U.s(2)
   q             //                                        .q(Z).
                 // This returns the runs of 1's and 0's in the binary
                 // representation of U, respectively.
      c          // Flatten into a single list.
        ml       // Map each item Z to Z.length.
           n gJ  // Sort the result and grab the item at index -1, or the last item.
                 // This returns the largest element in the list.
                 // Implicit: output result of last expression

2

R, 45 34 byte

max(rle(miscFuncs::bin(scan()))$l)

Đã sửa lỗi hiểu lầm ngớ ngẩn nhờ @rturnbull và @plannapus.


Có lẽ tôi đang thiếu một cái gì đó, nhưng không phải đầu vào được cho là một số nguyên, không phải là số nhị phân? Và chúng tôi đang tìm kiếm sự chạy tối đa 0hoặc 1, không chỉ 0, phải không?
rturnbull

@plannapus Tôi không biết trung thực. Phải bỏ qua thông số kỹ thuật hoàn toàn. Đã sửa bây giờ.
Billywob

2

PowerShell , 78 74 73 byte

([regex]::Matches([convert]::ToString("$args",2),'0+|1+')|% Le*|sort)[-1]

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

Ugh những phương thức .Net.

Điều này chỉ sử dụng một biểu thức chính để tìm (và khớp) các chuỗi liền kề của các số và số 0, sau đó nó lấy thuộc Lengthtính (với một mẫu mới mà tôi thấy sử dụng một tham số ít được biết đến ForEach-Object, để lưu 1 byte) của các đối tượng khớp kết quả, sắp xếp chúng, và đưa ra cái cuối cùng (lớn nhất).


1

J, 27 byte

>./>#&.>((1,2~:/\[)<;.1])#:

Cách tiếp cận hơi khác (và không may dài hơn) để trả lời dặm của .

Sử dụng:

    >./>#&.>((1,2~:/\[)<;.1])#:893
5

Giải trình

>./>#&.>((1,2~:/\[)<;.1])#:
                         #: Convert to base 2
        (               )   A fork
                       ]    Previous result
         (1,2~:/\[)         Find where each new sequence begins
                   <;.1     Cut the string of integers based on where each sequence begins and box them
    #&.>                    Count under open - open each box and count the items in it
>./>                        Open all the boxes and find the maximum value

Tôi không nghĩ rằng điều này là hợp lệ - nó không phải là một chức năng và một đoạn trích cũng vậy.
Conor O'Brien

@ ConorO'Brien Được rồi, tôi sẽ xem lại sau.
Gareth
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.