Bit run rundown


43

Dato un numero intero n > 0, genera la lunghezza della sequenza contigua più lunga 0o 1nella sua rappresentazione binaria.

Esempi

  • 6è scritto 110in binario; la sequenza più lunga è 11, quindi dovremmo tornare2
  • 16100004
  • 89311011111015
  • 13373711010001101000000110116
  • 111
  • 99655461001100000001111111010107


Possiamo assumere qualsiasi limite della dimensione dell'intero come 32 bit o 64 bit?
xnor

@xnor sì, puoi supporre che l'int sia max 32 bit
Arnaud

Risposte:


30

Python 2 , 46 45 byte

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

Provalo online!

Come funziona

XORing n e n / 2 (dividendo per 2 essenzialmente taglia l'ultimo bit), otteniamo un nuovo numero intero m i cui bit non impostati indicano la corrispondenza dei bit adiacenti in n .

Ad esempio, se n = 1337371 , abbiamo quanto segue.

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

Ciò riduce l'attività di ricerca della corsa più lunga di zero. Poiché la rappresentazione binaria di un intero positivo inizia sempre con un 1 , proveremo a trovare la stringa di cifre 10 * più lunga che appare nella rappresentazione binaria di m . Questo può essere fatto in modo ricorsivo.

Inizializza k come 1 . Ogni volta che f viene eseguita, verifichiamo innanzitutto se la rappresentazione decimale di k appare nella rappresentazione binaria di m . In tal caso, moltiplichiamo k per 10 e chiamiamo di nuovo f . In caso contrario, il codice a destra di andnon viene eseguito e restituiamo False .

Per fare questo, prima calcoliamo bin(k)[3:]. Nel nostro esempio, bin(k)restituisce '0b111100101110000010110'e 0b1all'inizio viene rimosso con [3:].

Ora, la -~prima della chiamata ricorsiva aumenta False / 0 una volta per ogni volta che f viene chiamato ricorsivamente. Una volta che 10 {j} ( 1 seguito da j ripetizioni di 0 ) non appare nella rappresentazione binaria di k , la corsa più lunga di zero in k ha lunghezza j - 1 . Poiché j - 1 zero consecutivi in k indicano j corrispondenti bit adiacenti in n , il risultato desiderato è j , che è ciò che otteniamo aumentando False / 0un totale di j volte.


2
Questo è davvero intelligente!
CraigR8806,

1
Wow, è intelligente. Non ci avrei mai pensato.
HyperNeutrino,

Bel trucco con i poteri di 10, ma non diventano lunghi con una L?
xnor

@xnor Alla fine, ma questa è solo una limitazione del tipo di dati. Anche le risposte C, JavaScript e PHP ne soffrono.
Dennis,

Ciò sarebbe gravemente non realizzabile se utilizzato in produzione. In breve (ghehe) golf raggiunto, buca in uno :)
JAK

17

Python 2, 46 byte

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

Provalo online

Estrae le cifre binarie dall'inverso nprendendo ripetutamente n/2e n%2. Tiene traccia della lunghezza della corsa corrente rdi cifre uguali reimpostandola su 0 se le ultime due cifre sono disuguali, quindi aggiungendo 1.

L'espressione ~-n/2%2indica se le ultime due cifre sono uguali, ovvero n0 o 3 modulo 4. Il controllo delle ultime due cifre insieme è risultato abbreviato rispetto al ricordare la cifra precedente.


14

05AB1E , 6 byte

b.¡€gM

Provalo online!

Spiegazione

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

2
HA! Finalmente! Un uso per , posso smettere di costringermi a provare ad usarlo.
Magic Octopus Urn,

@carusocomputing: abbastanza sicuro di averlo usato in un paio di risposte.
Emigna,

9

Mathematica, 38 byte

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

o

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

9

Python, 53 byte

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

Funzione lambda anonima.


9

Gelatina , 6 byte

BŒgL€Ṁ

Provalo online!

Come funziona

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

Rubino, 41 40 byte

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

Trova la sequenza più lunga di '1' in bo il suo inverso.

Grazie a manatwork per il salvataggio di 1 byte.


2
Non sono sicuro di altre versioni, ma in 2.3.1 non è necessario lo spazio tra %bi.
arte

Hai ragione, i numeri binari negativi iniziano con "..". Grazie.
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

Una soluzione ricorsiva con molta manipolazione dei bit. nmemorizza l'input, rmemorizza la lunghezza della corsa corrente, lmemorizza la lunghezza della corsa più lunga e dmemorizza la cifra precedente.

Test snippet

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
Stessa idea, ma usando più operazioni a bit e sfruttando la conversione predefinita da indefinita a 0. Sentiti libero di prendere in prestito: f=(x,b,n,m)=>x?f(x>>1,x&1,n=x&1^b||-~n,m>n?m:n):m
edc65

7

Rubino, 51 44 43 byte

Soluzione funzionale.

@manatwork è fatto di magia

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

Questo controlla cifre identiche consecutive o solo 0s consecutive ?
ngenesi

2
Risultato errato per 893.
orlp

@orlp non più! : D
Value Ink

1
Vorrei unire il 1 ° e 2 soluzioni: ->s{s.to_s(2).scan(/0+|1+/).map(&:size).max}.
arte

6

Python 2, 57 byte

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

Una soluzione ricorsiva. Potrebbe esserci una forma più breve per la magia un po '.


6

Perl, 43 byte

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

Contando lo shebang come uno, l'input è preso dallo stdin.

Provalo online!


Shebang conta come 0 byte.
Calcolatrice

Il consenso di @CalculatorFeline su meta è che #!perlconta come zero, no #!perl -p.
primo

@CalculatorFeline: Il -pcosto 1, supponendo che la tua riga di comando Perl avrebbe comunque un argomento (es. -eO -M5.010), in modo da poter inserire pa subito dopo uno dei trattini. Il #!perlè gratuito (anche se inutile).

Buono a sapersi. .
Calcolatrice

5

Pip , 16 byte

Sembra che ci debba essere un modo più breve per ottenere le piste della stessa cifra ...

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

Accetta input come argomento della riga di comando. Provalo online!

Spiegazione

     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}

Spiegazione:

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

Provalo online .


4

Haskell, 79 caratteri

maximum.map length.group.i

dove

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

O in versione non golfata:

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)

Spiegazione:

intToBinconverte un int in un elenco di cifre binarie (prima lsb). groupraggruppa sequenze contigue, tale che [1, 1, 0, 0, 0, 1]diventa [[1, 1],[0, 0, 0],[1]]. maximum . map lengthcalcola la lunghezza di ogni elenco interno e restituisce la lunghezza del più lungo.

Modifica: grazie a @xnor e @Laikoni per aver salvato i byte


2
groupnon è in Preludio di default, devi import Data.Listusarlo.
xnor

1
Si noti che è possibile utilizzare le guardie al posto di let: i n|(q,r)<-n`quotRem`2=r:i q. Consulta i nostri consigli sul golf Haskell . quotRempuò essere divMod. Penso che tu possa usare i 0=[]come base.
xnor

1
Utilizzando dive moddirettamente è ancora più breve: i n=mod n 2:i(div n 2).
Laikoni,

3

Pyth, 7 byte

heSr8.B

Esegui la codifica della lunghezza della corsa sulla stringa binaria, quindi ordinala in modo che le corse più lunghe arrivino per ultime, quindi prendi il primo elemento (la lunghezza) dell'ultimo elemento (la corsa più lunga) dell'elenco.

In pseudocodice:

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

3

J , 21 byte

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

Provalo online!

Spiegazione

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

Ciò converte la variabile intera 'a' in un array int8 binario, quindi conta il numero di volte in cui il risultato deve essere differenziato fino a quando non c'è zero nel risultato.

Sono nuovo qui. Questo tipo di input e one-liner è consentito dalle regole PCG?


3
Benvenuti in PPCG! Per impostazione predefinita, sono accettate solo funzioni o programmi completi (non frammenti di codice). Nel tuo caso, che significa che è necessario inserire acon a=input('');. Inoltre, alcuni consigli sul golf: ~ainvece di a==0. Ne hai davvero bisogno int8)?
Luis Mendo,

3

Ottava , 31 byte

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

Provalo online!

Spiegazione

Questa è una traduzione della mia risposta MATL. Il mio piano iniziale era un approccio diverso, vale a dire @(n)max(diff(find(diff([0 +dec2bin(n) 0])))). Ma si è scoperto che Octave ha una runlengthfunzione (di cui ho appena scoperto). Per impostazione predefinita, genera solo l'array di lunghezze di esecuzione, quindi il risultato desiderato è quello maxdi quell'array. L'output di dec2bin, che è un array di caratteri (stringa) contenente '0'e '1', deve essere convertito in un array numerico utilizzando +, poiché runlengthprevede input numerici.


3

Utilità Bash / Unix, 66 65 42 byte

Grazie a @DigitalTrauma per miglioramenti significativi (23 byte!).

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

Provalo online!


1
@DigitalTrauma Grazie per i miglioramenti, in particolare per l'inclusione di fold, che non è stata nel mio solito arsenale.
Mitchell Spector,

3

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

Modifiche:

  • Meno 1 byte (virgolette rimosse intorno all'espressione grep )

golfed

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

spiegato

 #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

Provalo online!


AFAIK, grep non fa né parte di bash né coreutils, sebbene sia mantenuto e distribuito da solo . Non sono sicuro di DC, ma era uno strumento autonomo nel mondo GNU. L'unico che fa parte dei coreutils è wc.
Moreaki,

@Moreaki, grep è POSIX, quindi qualsiasi risposta basata su shell implica che è già disponibile. dc non è POSIX ma è una parte standard di quasi tutti i sistemi * Nix in circolazione, quindi non viene normalmente menzionato come dipendenza separata.
Zeppelin,

Suppongo che siamo su due diversi treni di pensieri qui: il mio punto non era se grep fosse POSIX o no, il mio punto era che il titolo della tua presentazione per me indicava che uno avrebbe bisogno di bash + coreutils per far funzionare la tua soluzione, mentre questo non sembra il caso. La prima volta che l'ho letto, questa informazione mi confondeva. Se provi la tua soluzione su una shell bash spedita da macOS, non funzionerà; e non importa se hai installato coreutils o no; avresti bisogno di GNU grep per farlo funzionare.
Moreaki,

@Moreaki, sì, insisto solo sul sistema GNU, quando dico + coreutils, anche se non è sempre così. Ho aggiornato il titolo per essere più preciso.
Zeppelin,

2

Brachylog , 9 byte

$b@b:lotl

Provalo online!

Spiegazione

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

Versione formattata:

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 un approccio alternativo che accede alla stringa per indice a 118 byte, con spazi bianchi rimossi:

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

Grazie a manatwork per il codice.

Spiegazione

x.toString(2)

Converti il ​​numero in stringa binaria.

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

Dividi ogni carattere diverso (0 o 1) (questa regex cattura spazi vuoti ma possono essere ignorati)

map(y=>y.length)

Per ogni elemento dell'array ottenere la sua lunghezza e inserirlo nell'array restituito.

...

Convertire l'array in un elenco di argomenti ([1,2,3] -> 1,2,3)

Math.max()

Ottieni il numero più grande dagli argomenti.


1
Accreditando la soluzione Ruby di Value Ink per l'ispirazione, questa può essere trasformata in . O la stessa lunghezza: . 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))
arte

3
Penso che potresti dover aggiungere un predicato alla funzione di ordinamento sort((a,b)=>b-a). Per impostazione predefinita, la funzione di ordinamento si trova 10tra 1e 2.
Mama Fun Roll

Oppure potresti usare Math.max, come suggerito da Manatwork.
Mama Fun Roll

Wtf, ma sono numeri. JS per favore.

2

Meraviglia , 27 byte

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

Uso:

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

Converte in binario, corrisponde a ciascuna sequenza di 0 e 1, ottiene la lunghezza di ogni corrispondenza e ottiene il massimo.


Questo converte l'input in binario?
Laikoni,

oooooh ho perso quella parte. Soluzione rapida: P
Mama Fun Roll

2

Lotto, 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%

Porta della risposta di @ edc65. %2.. %4sarà vuoto alla prima chiamata, quindi devo scrivere le espressioni in modo tale che funzionino ancora. Il caso più generale è quello %3che ho dovuto scrivere come (%3+0). %2è più facile, come può essere0 o 1, che sono gli stessi in ottale, quindi 0%2funziona qui. %4si è rivelato ancora più semplice, poiché ho solo bisogno di sottrarlo. (%4-r>>5)viene utilizzato per confrontare lcon rquanto Batch di set/anon hai un operatore di confronto.


2

Dyalog APL , 22 byte

Treno di funzioni anonimo

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

⌈/∘(... Il massimo dei risultati del seguente treno funzionale anonimo ...

≢¨  il conteggio di ciascuno

⊢⊂⍨ partizione dell'argomento, in cui il partizionamento è determinato da quelli in

1, uno anteposto a

2≠/ la diseguaglianza a coppie di

 l'argomento

) applicata ai

2⊥⍣¯1 da-base-2 applicato negativo una volta (cioè a-base-2, una volta) a

 l'argomento

ProvaAPL online!


2

Japt, 15 byte

2o!q¢ c ml n gJ

Provalo online! oppure Verifica tutti i casi di test contemporaneamente .

Come funziona

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

Risolto un malinteso sciocco grazie a @rturnbull e @plannapus.


Forse mi manca qualcosa, ma l'ingresso non dovrebbe essere un numero intero, non un numero binario? E stiamo cercando la corsa massima di 0o di 1, non solo 0, giusto?
rturnbull,

@plannapus Non lo so onestamente. Deve aver perso completamente le specifiche. Riparato ora.
Billywob,

2

PowerShell , 78 74 73 byte

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

Provalo online!

Questi metodi .Net.

Questo utilizza solo una regex per trovare (e abbinare) sequenze contigue di uno e zero, quindi prende la Lengthproprietà (con un nuovo modello che ho trovato che utilizza un set di parametri poco noto di ForEach-Object, per salvare 1 byte) degli oggetti di corrispondenza risultanti, li ordina e produce l'ultimo (il più grande).


1

J, 27 byte

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

Un approccio leggermente diverso (e purtroppo più lungo) a risposta di miglia .

Uso:

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

Spiegazione

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

Non penso che questo sia valido - non è una funzione e quindi è un frammento.
Conor O'Brien,

@ ConorO'Brien Va bene, lo rivedrò più tardi.
Gareth,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.