Bit çalışma yıkık


43

Bir tamsayı verildiğinde , ikili gösterimdeki veya n > 0en uzun bitişik sırasının uzunluğunu çıkarın .01

Örnekler

  • 6110ikili olarak yazılmıştır ; en uzun dizi 11, bu yüzden geri dönmeliyiz.2
  • 16100004
  • 89311011111015
  • 13373711010001101000000110116
  • 111
  • 99655461001100000001111111010107


32 bit veya 64 bit gibi bir tamsayı boyutunda bir sınır alabilir miyiz?
xnor

@ xnor evet int'nin 32 bit olduğunu varsayabilirsin
Arnaud

Yanıtlar:


30

Python 2 , 46 45 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

Xoring tarafından n ve n / 2 (bölünmesiyle 2 esas olarak son bit kapalı pirzola), yeni bir tam sayı almak m olan sertleşmemiş bit bitişik bit eşleşen gösterir n .

Örneğin, n = 1337371 ise , aşağıdakilere sahibiz.

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

Bu, en uzun sıfır sırasını bulma görevini azaltır. Pozitif bir tamsayının ikili gösterimi her zaman 1 ile başladığından , m'nin ikili göstergesinde görünen en uzun 10 * rakam dizesini bulmaya çalışırız . Bu özyinelemeli yapılabilir.

Başlatma k olarak 1 . Her f çalıştırıldığında, ilk önce k'nin ondalık gösteriminin m'nin ikili gösterimi ile görünüp görünmediğini test ederiz . Eğer varsa, biz çarpın k tarafından 10 ve çağrı f tekrar. Olmazsa, sağındaki kod andçalıştırılmaz ve False döndürürüz .

Bunu yapmak için önce hesaplıyoruz bin(k)[3:]. Örneğimizde, bin(k)döner '0b111100101110000010110've 0b1başında ile kaldırılır [3:].

Şimdi, -~özyinelemeli çağrıdan önce her seferinde bir kez False / 0 artar f tekrarlanır. Bir kez 10 {j} ( 1 , ardından j tekrarlarının 0 ikili gösterimi görünmez) k , içinde sıfırların uzun çalışma k uzunluğu vardır j - 1 . Yana j - 1 ardışık sıfır k göstermektedir j eşleşen bitişik bit n , arzu edilen sonucu j biz arttırılmasıyla elde ne olduğu, yanlış / 0toplam j kez.


2
Bu gerçekten zekice!
CraigR8806,

1
Vay, bu çok zekice. Bunu asla düşünemezdim.
HyperNeutrino,

10 güçleri ile güzel hile, ancak bir L ile uzun sürmezler mi?
Xnor

@ xnor Sonunda, ancak bu sadece bir veri türü sınırlamasıdır. C, JavaScript ve PHP cevapları da bundan zarar görüyor.
Dennis

Üretimde kullanılırsa bu ciddi bir şekilde sürdürülemez. Kısacası (ghehe) golf başardı, bir delik açıldı :)
JAK

17

Python 2,46 bayt

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

Çevrimiçi deneyin

Gelen ekstreler ikili basamak nart arda alınarak tersten n/2ve n%2. Geçerli riki eşit hane uzunluğunu , son iki hane eşit değilse 0'a sıfırlayarak izler , ardından 1 ekler.

İfade ~-n/2%2, son iki hanenin eşit olup olmadığının bir göstergesidir, yani n0 veya 3 modulo 4.


14

05AB1E , 6 bayt

b.¡€gM

Çevrimiçi deneyin!

açıklama

b       # convert to binary
 .¡     # split at difference
   €g   # map length on each
     M  # take max

2
HA! En sonunda! Bir kullanım , kendimi kullanmaya çalışmak için kendimi zorlamayı bırakabilirim.
Magic Octopus Urn

@ carusocomputing: Kesinlikle birkaç cevapta kullandım.
Emigna

9

Mathematica, 38 bayt

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

veya

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

9

Python, 53 bayt

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

Anonim lambda işlevi.


9

Jöle , 6 bayt

BŒgL€Ṁ

Çevrimiçi deneyin!

Nasıl çalışır

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 bayt

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

En uzun '1' dizisini b veya tersi olarak bulun.

1 byte tasarruf için manatwork sayesinde.


2
Diğer sürümlerden emin değilim, ancak 2.3.1'de, aralarındaki boşluğa gerek yoktur %b.
Manatwork,

Haklısın, negatif ikili sayılar ".." ile başlar. Teşekkürler.
GB

7

JavaScript (ES6), 54 bayt

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

Çok fazla bit manipülasyon ile özyinelemeli bir çözüm. ngirişi rsaklar, geçerli çalışmanın luzunluğunu, en uzun çalışmanın uzunluğunu ve dönceki basamağı depolar.

Test pasajı

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
Aynı fikir, ancak daha fazla bit işlem kullanarak ve varsayılanın 0 f=(x,b,n,m)=>x?f(x>>1,x&1,n=x&1^b||-~n,m>n?m:n):m
unde

7

Ruby, 51 44 43 bayt

İşlev çözümü

@manatwork sihirden yapılmıştır

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

Bu ardışık aynı basamakları mı yoksa sadece ardışık 0s'leri kontrol ediyor mu?
ngenis,

2
893 için yanlış sonuç.
orlp,

@orlp artık değil! : D
Value Ink

1
Ben 1. ve 2. çözümler birleştirmek olacaktır: ->s{s.to_s(2).scan(/0+|1+/).map(&:size).max}.
Manatwork

6

Python 2, 57 bayt

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

Özyinelemeli bir çözüm. Biraz sihir için daha kısa bir form olabilir.


6

Perl, 43 bayt

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

Shebang'ı bir olarak sayarak girdi stdin'den alınır.

Çevrimiçi deneyin!


Shebanglar 0 bayt olarak sayılır.
Hesap MakinesiFeline

@CalculatorFeline meta üzerinde konsensüs olduğunu #!perlsıfıra değil, olduğu gibi sayar #!perl -p.
primo

@CalculatorFeline: -pPerl komut satırınızın yine de (ör. -eVeya -M5.010) bir argüman olduğu varsayımına bağlı olarak maliyet 1, bu nedenle tirelerden phemen sonra girebilirsiniz . #!perl(Gerekli olmamakla birlikte) içermez.

Bilmek güzel. .
Hesap MakinesiFeline

5

Pip , 16 bayt

Görünüşe göre aynı rakamlarla koşmak için daha kısa bir yol olmalı ...

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

Komut satırı argümanı olarak girdi alır. Çevrimiçi deneyin!

açıklama

     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 bayt

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

Açıklama:

{                                 }   # 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

Çevrimiçi deneyin .


4

Haskell, 79 karakter

maximum.map length.group.i

nerede

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

Veya ungolfed versiyonunda:

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)

Açıklama:

intToBinint'yi ikilik hanelerin listesine dönüştürür (önce lsb). olur groupgibi bitişik dizileri gruplandırır . Her iç liste için uzunluğunu hesaplar ve en uzununun uzunluğunu döndürür.[1, 1, 0, 0, 0, 1][[1, 1],[0, 0, 0],[1]]maximum . map length

Düzenleme: Bayt kaydetmek için @xnor ve @Laikoni sayesinde


2
groupVarsayılan olarak Prelude değil, import Data.Listkullanmak için yapmanız gerekenler .
xnor

1
Eğer yerine korumaları kullanabileceğinizi unutmayın let: i n|(q,r)<-n`quotRem`2=r:i q. Haskell golf ipuçlarımıza bakın . quotRemolabilir divMod. Bence i 0=[]temel dava olarak kullanabilirsiniz .
Xnor

1
Kullanılması divve moddoğrudan bile kısadır: i n=mod n 2:i(div n 2).
Laikoni

3

Pyth, 7 bayt

heSr8.B

İkili dizede çalıştırma uzunluğu kodlamasını yapın, ardından en uzun çalıştırmaların son geleceği şekilde sıralayın, ardından listenin son öğesinin ilk uzunluğunu (en uzun koşuyu) alın.

Sözde kodda:

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

3

J , 21 bayt

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

Çevrimiçi deneyin!

açıklama

[:>./#:#;.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 bayt

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

Bu, 'a' tamsayı değişkenini bir ikili int8 dizisine dönüştürür, ardından sonuçta sıfırı olmayana kadar sonucun ne kadar farklılaştırılacağını sayar.

Ben burada yeniyim. PCG kuralları bu tür bir girişe ve bir linere izin veriyor mu?


3
PPCG'ye Hoşgeldiniz! Varsayılan olarak, yalnızca işlevler veya tam programlar (kod parçacıkları değil) kabul edilir. Senin durumunda aracı girmek gerektiğini aile a=input('');. Ayrıca, bazı golf önerileri: ~ayerine a==0. Gerçekten ihtiyacınız var int8mı?
Luis Mendo,

3

Oktav , 31 bayt

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

Çevrimiçi deneyin!

açıklama

Bu MATL cevabımın bir çevirisidir. İlk planım, yani farklı bir yaklaşımdı @(n)max(diff(find(diff([0 +dec2bin(n) 0])))). Ancak, Octave'nin bir runlengthişlevi olduğu ortaya çıktı (ki bunu daha yeni öğrendim). Varsayılan olarak yalnızca çalışma uzunlukları dizisini çıkarır, bu nedenle istenen sonuç maxdizinin sonucudur . Sayısal bir girdi beklediğinden , ve dec2biniçeren bir char dizisi olan (string) çıktısının, sayısal bir diziye dönüştürülmesi gerekir .'0''1'+runlength


3

Bash / Unix yardımcı programları, 66 65 42 bayt

Önemli gelişmeler için @DigitalTrauma için teşekkürler (23 byte!).

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

Çevrimiçi deneyin!


1
@DigitalTrauma Özellikle her zamanki cephaneliğimde olmayan katlamayı dahil ettiğiniz için iyileştirmeler için teşekkürler.
Mitchell Spector

3

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

DÜZENLEMELER:

  • Eksi 1 bayt ( grep ifadesi etrafındaki tırnak işaretleri kaldırıldı )

golfed

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

Açıklaması

 #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

Çevrimiçi Deneyin!


AFAIK, grep ne bash ne de coreutils'in bir parçasını oluşturmaz, ancak kendi başına tutulur ve dağıtılır . Dc hakkında emin değilim, ancak GNU dünyasında bağımsız bir araç olarak kullanılıyordu. Coreutils'in tek oluşturan kısmı wc'dir.
Moreaki

@Moreaki, grep POSIX, bu nedenle herhangi bir kabuk tabanlı cevap zaten mevcut olduğunu ima eder. dc POSIX değil, etrafındaki hemen hemen her * Nix sisteminin standart bir parçası olduğu için normalde ayrı bir bağımlılık olarak da ifade edilmez.
zeplin

Burada iki farklı düşünce treninde olduğumuzu düşünüyorum: noktama göre grep POSIX olmasaydı değildi, benim açımdan bana gönderdiğin unvanın, çözümün işe yaraması için bash + coreutils'e ihtiyacı olacağını belirtti. bu durum böyle gözükmüyor. Önce onu okuduğumda, bu bilgi benim için kafa karıştırıcıydı. Çözümünüzü bir macOS tarafından gönderilen bash kabuğunda deneyin, işe yaramaz; coreutils kurup kurmamanız önemli değil; Çalışması için GNU grep'e ihtiyacınız olacak.
Moreaki

@Moreaki, evet, ben sadece + coreutils derken GNU sistemini ima ediyorum, her zaman durum böyle değil. Başlığı daha kesin olacak şekilde güncelledim.
zeplin

2

Brachylog , 9 bayt

$b@b:lotl

Çevrimiçi deneyin!

açıklama

$b          List of binary digits of the input
  @b        Runs of consecutive identical digits in that list
    :lo     Order those runs by length
       tl   Output is the length of the last one

2

C #, 106 bayt

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

Biçimlendirilmiş versiyon:

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

Ve dizgiye endeksi ile 118 bayttan erişen alternatif bir yaklaşım, boşluklar kaldırılmış olarak:

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 Bayt

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

Kod için yapılan çalışmalara teşekkür ederiz .

açıklama

x.toString(2)

Sayıyı ikili dizgiye dönüştürün.

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

Her farklı karakteri bölme (0 veya 1) (bu regex boş alanları kaplar ancak göz ardı edilebilir)

map(y=>y.length)

Dizinin her elemanı için uzunluğunu alın ve döndürülen diziye koyun.

...

Diziyi argüman listesine dönüştür ([1,2,3] -> 1,2,3)

Math.max()

Argümanlardan en büyük sayıyı alın.


1
Kredilendirme By Değer Mürekkep 'ın Yakut çözümü ilham için, bu dönüştürülebilir x=>x.toString(2).split(/(0+|1+)/g).map(y=>y.length).sort().pop(). Veya aynı uzunluk: x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.length)).
Manatwork,

3
Sıralama işlevine bir işaret eklemek zorunda kalabileceğinizi düşünüyorum sort((a,b)=>b-a). Varsayılan olarak, sıralama işlevi yerleştirir 10arasında 1ve 2.
Mama Fun Roll

Veya, Manatwork'ün önerdiği gibi Math.max'i kullanabilirsiniz.
Mama Fun Roll

WTF, ama onlar sayılar. JS lütfen.

2

Wonder , 27 bayt

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

Kullanımı:

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

İkililere dönüştürür, 0 ve 1'lerin her bir dizisiyle eşleşir, her eşleşmenin uzunluğunu alır ve en yüksek değeri alır.


Bu, girişi ikiliye dönüştürür mü?
Laikoni

oooooh Bu kısmı özledim. Hızlı düzeltme: P
Mama Fun Roll

2

Toplu iş, 102 bayt

@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%

@ Edc65'in cevabının limanı. %2.. %4ilk aramada boş olacak, bu yüzden ifadeleri hala çalışacak şekilde yazmak zorundayım. En genel durumda %3ben yazmak zorunda olan (%3+0). %2daha kolay, sadece olabileceği gibi, 0ya da 1sekizlik olarak da aynı, 0%2burada çalışıyor. %4daha kolay olduğu ortaya çıktı, çünkü ondan çıkarmam gerekiyor. (%4-r>>5)karşılaştırmak için kullanılır lile rToplu en olarak set/abir karşılaştırma operatörü yok.


2

Dyalog APL , 22 bayt

Anonim işlev treni

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

⌈/∘(... Aşağıdaki anonim fonksiyon dizisinin sonuçlarının maksimum değeri ...

≢¨  her birinin taksiti

⊢⊂⍨ Argümanın bölümlenmesi, burada bölümlemenin

1, biri için hazırlanmış

2≠/ çift ​​eşitsiz

 argüman

) uygulanan

2⊥⍣¯1 baz-2'den bir defa negatif uygulandı (yani, baz-2'ye bir kez)

 argüman

TryAPL çevrimiçi!


2

Japt, 15 bayt

2o!q¢ c ml n gJ

Çevrimiçi test edin! veya Tüm test durumlarını bir kerede doğrulayın .

Nasıl çalışır

                 // 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 bayt

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

@ Rturnbull ve @plannapus sayesinde aptalca bir yanlış anlaşılma düzeltildi.


Belki de bir şeyleri özlüyorum, ama giriş tam sayı olmalı, ikili sayı değil mi? Ve maksimum vadede aradığınız 0ya da 1sadece, 0değil mi?
rturnbull

@plannapus Dürüstçe bilmiyorum. Spesifikasyonu tamamen kaçırmış olmalı. Şimdi düzeltildi.
Billywob

2

PowerShell , 78 74 73 bayt

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

Çevrimiçi deneyin!

Ugh bunlar. Net yöntemleri.

Bu sadece bir ve sıfırın bitişik dizilerini bulmak (ve eşleştirmek) için bir regex kullanır, daha sonra elde edilen eşleşme nesnelerinin özelliklerini (1 byte tasarruf etmek Lengthiçin az bilinen bir parametre kümesi kullandığını buldum ForEach-Object) onları sıralar ve sonuncusunu (en büyüğü) çıkarır.


1

J, 27 bayt

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

Biraz farklı (ve ne yazık ki daha uzun) yaklaşımı cevabına .

Kullanımı:

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

açıklama

>./>#&.>((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

Bunun geçerli olduğunu sanmıyorum - bu bir işlev değil ve bir pasaj.
Conor O'Brien,

@ ConorO'Brien Tamam, daha sonra tekrar bakacağım.
Gareth
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.