Resumo da execução de bits


43

Dado um número inteiro n > 0, imprima o comprimento da maior sequência contígua de 0ou 1em sua representação binária.

Exemplos

  • 6é escrito 110em binário; a sequência mais longa é 11, então devemos retornar2
  • 16100004
  • 89311011111015
  • 13373711010001101000000110116
  • 111
  • 99655461001100000001111111010107


Podemos assumir qualquer limite do tamanho do número inteiro, como 32 ou 64 bits?
Xnor

@xnor sim, você pode assumir o int é de 32 bits max
Arnaud

Respostas:


30

Python 2 , 46 45 bytes

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

Experimente online!

Como funciona

Ao XORing n e n / 2 (a divisão por 2 corta essencialmente o último bit), obtemos um novo número inteiro m cujos bits não definidos indicam os bits adjacentes correspondentes em n .

Por exemplo, se n = 1337371 , temos o seguinte.

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

Isso reduz a tarefa de encontrar a execução mais longa de zeros. Como a representação binária de um número inteiro positivo sempre começa com 1 , tentaremos encontrar a seqüência de caracteres 10 * mais longa que aparece na representação binária de m . Isso pode ser feito recursivamente.

Inicialize k como 1 . Toda vez que f é executado, primeiro testamos se a representação decimal de k aparece na representação binária de m . Nesse caso, multiplicamos k por 10 e chamamos f novamente. Caso contrário, o código à direita de andnão é executado e retornamos False .

Para fazer isso, primeiro calculamos bin(k)[3:]. Em nosso exemplo, bin(k)retorna '0b111100101110000010110', e o 0b1no início é removido com [3:].

Agora, a -~chamada anterior recursiva aumenta Falso / 0 uma vez para cada vez que f é chamado recursivamente. Uma vez que 10 {j} ( 1 seguido de j repetições de 0 ) não aparece na representação binária de k , o maior número de zeros em k tem comprimento j - 1 . Como j - 1 zeros consecutivos em k indicam j bits adjacentes correspondentes em n , o resultado desejado é j , que é o que obtemos incrementando False / 0um total de j vezes.


2
Isso é realmente inteligente!
precisa saber é o seguinte

1
Uau, isso é inteligente. Nunca poderia ter pensado nisso.
precisa saber é o seguinte

Truque legal com os poderes de 10, mas eles não ficam muito tempo com um L?
Xnor

@xnor Eventualmente, mas isso é apenas uma limitação do tipo de dados. As respostas C, JavaScript e PHP também sofrem com isso.
Dennis

Isso seria seriamente insustentável se usado na produção. Em suma (ghehe) golf alcançado, furo em um :)
JAK

17

Python 2, 46 bytes

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

Experimente online

Extrai dígitos binários de nmodo inverso, usando n/2e repetidamente n%2. Rastreia o comprimento da execução atual rde dígitos iguais, redefinindo-o para 0 se os dois últimos dígitos forem desiguais e adicionando 1.

A expressão ~-n/2%2é um indicador de se os dois últimos dígitos são iguais, ou seja, né 0 ou 3 do módulo 4. Verificar os dois últimos dígitos juntos diminuiu mais do que lembrar o dígito anterior.


14

05AB1E , 6 bytes

b.¡€gM

Experimente online!

Explicação

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

2
HA! Finalmente! Como uso , posso parar de me forçar a tentar usá-lo.
Magic Octopus Urn

@carusocomputing: Tenho certeza de que já o usei em algumas respostas.
Emigna

9

Mathematica, 38 bytes

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

ou

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

9

Python, 53 bytes

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

Função lambda anônima.


9

Gelatina , 6 bytes

BŒgL€Ṁ

Experimente online!

Como funciona

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 bytes

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

Encontre a sequência mais longa de '1' em b ou em sua inversa.

Agradecimentos ao manatwork por economizar 1 byte.


2
Não tenho certeza sobre outras versões, mas na 2.3.1 não há necessidade de espaço entre as %b.
manatwork

Você está certo, números binários negativos começam com "..". Obrigado.
GB

7

JavaScript (ES6), 54 bytes

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

Uma solução recursiva com muita manipulação de bits. narmazena a entrada, rarmazena a duração da execução atual, larmazena a duração da execução mais longa e darmazena o dígito anterior.

Snippet de teste

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
Mesma idéia, mas usando operações mais bits e explorando a conversão padrão de indefinido a 0. Sinta-se livre para pedir: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 bytes

Solução de função.

@manatwork é feito de mágica

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

Isso verifica dígitos idênticos consecutivos ou apenas 0s consecutivos ?
Ngenisis

2
Resultado incorreto para 893.
orlp 13/01

@orlp não mais! : D
Value Ink

1
Gostaria de combinar a 1ª e 2ª soluções: ->s{s.to_s(2).scan(/0+|1+/).map(&:size).max}.
manatwork

6

Python 2, 57 bytes

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

Uma solução recursiva. Pode haver uma forma mais curta para a mágica do bit.


6

Perl, 43 bytes

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

Contando o shebang como um, a entrada é obtida de stdin.

Experimente online!


Shebangs contam como 0 bytes.
CalculatorFeline

O consenso @CalculatorFeline sobre meta é que #!perlconta como zero, não #!perl -p.
Primo

@CalculatorFeline: O -pcusto é 1, supondo que sua linha de comando Perl tenha um argumento de qualquer maneira (por exemplo, -eou -M5.010), para que você possa entrar plogo após um dos hífens. O #!perlé gratuito (embora desnecessário).

Bom saber. .
CalculatorFeline

5

Pip , 16 bytes

Parece que deve haver uma maneira mais curta de obter as execuções do mesmo dígito ...

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

Recebe entrada como argumento da linha de comando. Experimente online!

Explicação

     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 bytes

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

Explicação:

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

Experimente online .


4

Haskell, 79 caracteres

maximum.map length.group.i

Onde

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

Ou na versão ungolfed:

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)

Explicação:

intToBinconverte um int em uma lista de dígitos binários (lsb primeiro). groupagrupa sequências contíguas, de modo que [1, 1, 0, 0, 0, 1]se tornem [[1, 1],[0, 0, 0],[1]]. maximum . map lengthcalcula para cada lista interna seu comprimento e retorna o comprimento do maior.

Edit: Obrigado a @xnor e @Laikoni por salvar bytes


2
groupnão está no Prelude por padrão, você precisa import Data.Listusá-lo.
Xnor

1
Note que você pode usar guardas no lugar de let: i n|(q,r)<-n`quotRem`2=r:i q. Veja nossas dicas de golfe em Haskell . quotRempode ser divMod. Eu acho que você pode usar i 0=[]como o caso base.
Xnor

1
Usando dive moddiretamente é ainda menor: i n=mod n 2:i(div n 2).
Laikoni

3

Pitão, 7 bytes

heSr8.B

Execute a codificação de comprimento na cadeia binária e, em seguida, classifique-a para que as execuções mais longas cheguem por último e, em seguida, pegue o primeiro elemento (o comprimento) do último elemento (a execução mais longa) da lista.

No pseudocódigo:

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

3

J , 21 bytes

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

Experimente online!

Explicação

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

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

Isso converte a variável inteira 'a' em uma matriz binária int8 e conta o número de vezes que o resultado deve ser diferenciado até que não haja zero no resultado.

Eu sou novo aqui. Esse tipo de entrada e uma linha são permitidos pelas regras do PCG?


3
Bem-vindo ao PPCG! Por padrão, apenas funções ou programas completos (sem trechos de código) são aceitos. No seu caso, isso significa que você precisa de entrada acom a=input('');. Além disso, alguns conselhos de golfe: em ~avez de a==0. Você realmente precisa int8)?
Luis Mendo

3

Oitava , 31 bytes

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

Experimente online!

Explicação

Esta é uma tradução da minha resposta MATL. Meu plano inicial era uma abordagem diferente, a saber @(n)max(diff(find(diff([0 +dec2bin(n) 0])))). Mas acontece que o Octave tem uma runlengthfunção (sobre a qual acabei de descobrir). Por padrão, ele gera apenas a matriz de comprimentos de execução; portanto, o resultado desejado é o maxdessa matriz. A saída de dec2bin, que é uma matriz de caracteres (string) contendo '0'e '1', precisa ser convertida em uma matriz numérica usando +, porque runlengthespera entrada numérica.


3

Utilitários Bash / Unix, 66 65 42 bytes

Obrigado a @DigitalTrauma por melhorias significativas (23 bytes!).

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

Experimente online!


1
@DigitalTrauma Obrigado pelas melhorias, especialmente por incluir fold, que não está no meu arsenal habitual.
Mitchell Spector

3

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

EDITAR% S:

  • Menos 1 byte (aspas removidas em torno da expressão grep )

Golfe

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

Explicado

 #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

Experimente Online!


O AFAIK, grep não faz parte do bash nem do coreutils, embora seja mantido e distribuído por si próprio . Não tenho certeza sobre dc, mas costumava ser uma ferramenta independente no mundo GNU. O único que faz parte dos coreutils é o wc.
Moreaki 15/01/19

@ Moreaki, grep é POSIX, portanto, qualquer resposta baseada em shell implica que já esteja disponível. O dc não é POSIX, mas é parte padrão de quase todos os sistemas * Nix existentes, portanto, normalmente não é mencionado também como uma dependência separada.
Zeppelin

Eu acho que estamos em duas linhas de pensamento diferentes aqui: meu ponto não era se grep era POSIX ou não, meu ponto era que o título da sua submissão indicava que seria necessário bash + coreutils para fazer sua solução funcionar, enquanto este parece não ser o caso. Quando li pela primeira vez, essa informação foi confusa para mim. Se você tentar sua solução em um shell bash enviado para o macOS, ela não funcionará; e não importa se você instalou o coreutils ou não; você precisaria do GNU grep para fazê-lo funcionar.
Moreaki 24/01

@ Moreaki, sim, eu apenas implico o sistema GNU, quando digo + coreutils, nem sempre é esse o caso. Atualizei o título para ser mais preciso.
Zeppelin

2

Braquilog , 9 bytes

$b@b:lotl

Experimente online!

Explicação

$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 bytes

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

Versão formatada:

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

E uma abordagem alternativa de acessar a string pelo índice em 118 bytes, com o espaço em branco removido:

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 bytes

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

Obrigado ao manatwork pelo código.

Explicação

x.toString(2)

Converta o número em sequência binária.

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

Divida cada caractere diferente (0 ou 1) (esse regex captura espaços vazios, mas eles podem ser ignorados)

map(y=>y.length)

Para cada elemento da matriz, obtenha seu comprimento e coloque-o na matriz retornada.

...

Converter matriz em lista de argumentos ([1,2,3] -> 1,2,3)

Math.max()

Obtenha o maior número dos argumentos.


1
Creditando Valor Ink 's solução de Ruby para a inspiração, este pode ser transformado em x=>x.toString(2).split(/(0+|1+)/g).map(y=>y.length).sort().pop(). Ou o mesmo comprimento: x=>Math.max(...x.toString(2).split(/(0+|1+)/g).map(y=>y.length)).
manatwork

3
Eu acho que você pode ter que adicionar um predicado à função de classificação sort((a,b)=>b-a). Por padrão, a função de classificação coloca 10entre 1e 2.
Mama Fun Roll

Ou você pode usar o Math.max, como sugerido pelo manatwork.
Mama Fun Roll

Wtf, mas são números. JS por favor.

2

Maravilha , 27 bytes

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

Uso:

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

Converte em binário, corresponde a cada sequência de 0 e 1, obtém a duração de cada correspondência e o máximo.


Isso converte a entrada em binário?
Laikoni

oooooh eu perdi essa parte. Solução rápida: P
Mama Fun Roll

2

Lote, 102 bytes

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

Porto da resposta do @ edc65. %2.. %4ficará vazio na primeira chamada, então eu tenho que escrever as expressões de forma que elas ainda funcionem. O caso mais geral é o %3qual eu tive que escrever como (%3+0). %2é mais fácil, pois só pode ser 0ou 1, que são iguais em octal, então 0%2funciona aqui. %4acabou sendo ainda mais fácil, pois só preciso subtraí-lo. (%4-r>>5)é usado para comparar lcom ra do lote de set/anão ter um operador de comparação.


2

Dyalog APL , 22 bytes

Trem de função anônima

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

⌈/∘(... O máximo dos resultados do seguinte trem de função anônimo ...

≢¨  a contagem de cada

⊢⊂⍨ partição do argumento, onde a partição é determinada por aqueles em

1, um anexado a

2≠/ o desigual par de

 o argumento

) aplicado a

2⊥⍣¯1 da base 2 aplicada negativa uma vez (ou seja, à base 2, uma vez) para

 o argumento

TryAPL online!


2

Japonês, 15 bytes

2o!q¢ c ml n gJ

Teste online! ou Verifique todos os casos de teste de uma só vez .

Como funciona

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

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

Corrigido um mal entendido graças a @rturnbull e @plannapus.


Talvez esteja faltando alguma coisa, mas a entrada não deveria ser um número inteiro, não um número binário? E estamos procurando a execução máxima de 0ou de 1, não apenas 0, certo?
precisa saber é o seguinte

@ Plannapus Eu não sei honestamente. Deve ter perdido completamente as especificações. Corrigido agora.
Billywob

2

PowerShell , 78 74 73 bytes

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

Experimente online!

Ugh esses métodos .Net.

Isso apenas usa uma regex para encontrar (e corresponder) seqüências contíguas de uns e zeros, e leva o Length propriedade (com um novo padrão que descobri que usa um conjunto de parâmetros pouco conhecido de ForEach-Object, para salvar 1 byte) dos objetos de correspondência resultantes, classifica-os e gera o último (o maior).


1

J, 27 bytes

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

Uma abordagem ligeiramente diferente (e infelizmente mais longa) para resposta das milhas .

Uso:

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

Explicação

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

Eu não acho que isso seja válido - não é uma função e também é um trecho.
Conor O'Brien

@ ConorO'Brien Ok, vou ver novamente mais tarde.
Gareth
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.