Calcular la serie más larga de 1 en el valor binario de un entero

32

Gol

Dado un entero no negativo, cree una función que devuelva la posición inicial del número de los 1 consecutivos más grandes en el valor binario de ese entero.

Cuando se le da una entrada 0, regrese 0.

Si el número tiene varias líneas de igual longitud, debe devolver la posición de la última línea.

Entrada

Un entero mayor o igual a 0.

Salida

Un entero calculado como se explica a continuación.

Reglas

  • Este es el código de golf, por lo que gana el código más corto en bytes en cada idioma.
  • Las lagunas estándar están prohibidas.

Ejemplos y casos de prueba

Ejemplo 1

  • Su función se pasa al entero 142
  • 142 es igual a 10001110 en binario
  • La racha más larga es "111" (una racha de tres)
  • La racha comienza en la posición 2 ^ 1
  • Su función devuelve 1 como resultado

Ejemplo 2

  • Su función se pasa al entero 48
  • 48 es igual a 110000 en binario
  • La racha más larga es "11" (una racha de dos)
  • La racha comienza en la posición 2 ^ 4
  • Su función devuelve 4 como resultado

Ejemplo 3

  • Su función se pasa al entero 750
  • 750 es igual a 1011101110 en binario
  • La racha más larga es "111" (una racha de tres)
  • Como hay dos líneas de igual longitud, devolvemos la línea posterior.
  • La racha posterior comienza en la posición 2 ^ 5
  • Su función devuelve 5 como resultado
De facto
fuente
1
Necesita un criterio ganador, como code-golf
Okx
@Okx Se había mencionado en el propio cuerpo, así que agregué la etiqueta.
totalmente humano
Asegúrate de que la gente haga la prueba 0. Ese es un caso de prueba importante.
mbomb007
2
En lugar de "última racha" o "última racha", sugeriría "racha con el mayor valor posicional".
aschepler
@Okx ¿Por qué es necesario un criterio ganador? ¿Por qué no puede ser simplemente un rompecabezas?
corsiKa

Respuestas:

21

Jalea , 10 8 bytes

Ba\ÐƤṀċ¬

Pruébalo en línea!

Cómo funciona

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.
Dennis
fuente
¡Felicidades!
Defacto
24

JavaScript (ES6), 41 40 36 34 bytes

Guardado 4 bytes gracias a @ThePirateBay

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

Casos de prueba

¿Cómo?

Caso general x> 0

Recurrimos Y la entrada x con x / 2, que reduce progresivamente los patrones de los bits establecidos consecutivos hasta que solo quede el bit más a la derecha de la secuencia. Mantenemos una copia del último valor distinto de cero y determinamos la posición de su bit más significativo redondeando su logaritmo de base 2.

A continuación se detallan los pasos que seguimos para x = 750 ( 1011101110 en binario).

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

Caso de borde x = 0

El caso especial x = 0lleva inmediatamente a Math.log2(0) | 0. El logaritmo de 0evalúa -Infinityy el binario OR a nivel de bit fuerza una coerción a un entero de 32 bits. En cumplimiento con la especificación de la operación abstracta ToInt32 , esto proporciona lo esperado 0:

Si el número es NaN , +0 , −0 , + ∞ o −∞ , devuelve +0

Arnauld
fuente
Esto 0produce errores en la entrada , que forma parte del rango de entrada.
Justin Mariner
@JustinMariner fijo.
Arnauld
¿Qué pasa en Math.log2(k)|0lugar de 31-Math.clz32(k)? ¿O me estoy perdiendo algo?
@ThePirateBay Math.log2(k)|0es en realidad más corto y más simple para el caso especial x=0. Gracias. :)
Arnauld
1
Muy buen algoritmo, y buena explicación. Lo implementé en 14 bytes de código de máquina x86 .
Peter Cordes
12

código de máquina x86, 14 bytes

Usando @ algoritmo de Arnauld de x &= x>>1y tomando la posición de bit más alta establecida en el paso anterior xse hace 0.

Llamable desde C / C ++ con firma unsigned longest_set(unsigned edi);en el x86-64 System V ABI. Los mismos bytes de código de máquina se decodificarán de la misma manera en el modo de 32 bits, pero las convenciones de llamada estándar de 32 bits no ponen el primer argumento edi. (Cambio de la entrada de registro para ecxo edxpara Windows _fastcall/ _vectorcallo gcc -mregparmse podría hacer sin romper nada.)

   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

La BSRinstrucción de x86 (Bit Scan Reverse) es perfecta para esto, ya que nos proporciona el índice de bits directamente, en lugar de contar los ceros a la izquierda. ( bsrno produce directamente 0 para input = 0 como lo 32-lzcnt(x)haría, pero necesitamos bsr = 31-lzcnt para entradas que no sean cero, por lzcntlo que ni siquiera guardaría instrucciones, y mucho menos contar bytes. Poner a cero eax antes de que el bucle funcione debido a bsr' s comportamiento semioficial de dejar el destino sin modificar cuando la entrada es cero).

Esto sería aún más corto si pudiéramos devolver la posición MSB de la carrera más larga. En ese caso, lea ecx, [rdi+rdi](3 bytes) copiaría + desplazamiento a la izquierda en lugar de mov+ shr(4 bytes).

Vea este enlace TIO para una llamada asm queexit(longest_set(argc-1));

Prueba con un bucle de 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
Peter Cordes
fuente
1
¡Agradable! Una nota para aquellos que (como yo) están más familiarizados con otros dialectos de ensamblaje: la mnemónica x86 BSR significa "Bit Scan Reverse", no "Branch to SubRoutine".
Arnauld
@Arnauld: buen punto, editado para decodificar el mnemónico, además de tener un enlace a la entrada del manual de referencia de insn.
Peter Cordes
5

Jalea , 19 17 11 bytes

HÐĿ&\ḟ0ṪBL’

Pruébalo en línea!

-6 (!) Bytes gracias a las agudas observaciones de @ Dennis

Cómo funciona

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
fireflame241
fuente
Errores para 0, que está en el rango de entrada.
Sr. Xcoder
@ Mr.Xcoder Fixed
fireflame241
Puede guardar un byte para la solución conȯ-µ...
Jonathan Allan
@ JonathanAllan No entiendo cómo OR-ing ayudaría. Tienes codigo
fireflame241
1
Como Bsiempre devuelve una matriz que comienza con un 1 , BUṪMṪ’×Ṡpuede convertirse ṪBL’. Además, no necesita el y ḟ0ahorra un byte ¹Ðf.
Dennis
5

Python 2 , 45 bytes

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

Pruébalo en línea!

¡Ahorré muchos bytes gracias a Dennis! (El aviso en len(bin(...))-3lugar de math.frexp)

Gracias a @xnor por encontrar un error, que afortunadamente fue fácilmente reparable.

Sr. Xcoder
fuente
Esto parece dar respuestas incorrectas como x=3, creo, porque los and/orcortocircuitos son incorrectos cuando la función devuelve 0.
xnor
@xnor Gracias por notar eso! Está arreglado.
Sr. Xcoder
4

Perl 6 ,45 35 bytes

Esta versión altamente mejorada es cortesía de @nwellnhof.

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

Pruébalo en línea!

Ramillies
fuente
Simplemente puede combinar con :gpara obtener todas las coincidencias. Con el operador inteligente partido, pude campo se reduce a 40 bytes:{sort(.base(2).flip~~m:g/1+/).tail.from}
nwellnhof
Y a 35 bytes:{.msb+1-(.base(2)~~m:g/1+/).max.to}
nwellnhof
@nwellnhof, muchas gracias. De alguna manera me perdí :gy no descubrí cómo puedo usar el adverbio con el operador smartmatch. También el.msb método es bastante útil aquí y no lo sabía antes.
Ramillies
3

Python 2 , 89 78 bytes

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

Pruébalo en línea!

EDITAR: Guardado 11 bytes gracias al Sr. Xcoder.

Chas Brown
fuente
86 bytes
Sr. Xcoder
78 bytes
Sr. Xcoder
@ Mr.Xcoder También pensé en eso, aunque la pregunta específicamente pide escribir una función.
Jonathan Frech
@ JonathanFrech No creo que el OP realmente signifique función . Probablemente solo un término genérico.
Sr. Xcoder
@ Mr.Xcoder Por favor explique esto. Gracias,
lifebalance
3

05AB1E , 14 12 11 bytes

bDγàŠrkrJgα

Pruébalo en línea! o ejecutar casos de prueba .

Explicación

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
Justin Mariner
fuente
3

J , 18 17 bytes

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

Pruébalo en línea!

Explicación

(#-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
millas
fuente
Muy hábil. Sin embargo, no estoy seguro de entender completamente lo que está sucediendo con la conversión de base mixta. ¿Por qué cuenta el número de consecutivos al final de la cadena? Además, si las bases que se especifican en la xdíada son todas 0 y 1, ¿qué significa eso? Un número base 2 tiene dígitos 0y 1, entonces, un 1número base tiene dígitos ... 0? entonces, ¿qué significa un 1en ese contexto? ¿Y es un 0número base siempre 0?
Jonás
@ Jonás Es más debido a cómo se implementa la conversión de base mixta. x #. yprimero computa w =: */\. }. x , 1luego regresa+/ w * y
millas
Entonces, ¿consideraría esto un truco de golf en lugar de un uso legítimo #., ya que depende de los detalles de implementación internos en lugar de la API pública?
Jonás
3

C # (.NET Core) , 64 60 bytes

T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)

Pruébalo en línea!

AC # versión de la respuesta @ Arnauld

Expresiones de gratitud

4 bytes guardados gracias a Kevin Cruijssen.

C # (.NET Core) , 131 123 + 18 = 141 bytes

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

Pruébalo en línea!

+18 bytes para using System.Linq;

Expresiones de gratitud

8 bytes guardados gracias a Grzegorz Puławski.

Degolfed

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) , 164161 bytes

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

Pruébalo en línea!

Un noLinq solución, que estoy seguro podría mejorarse, aunque nada es evidente de inmediato.

Degolfed

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
}
Ayb4btu
fuente
1
Puede guardar 8 bytes abandonando ren la primera respuesta: tio.run/##dY9RS8MwFIWfza/…
Grzegorz Puławski
Puede guardar dos bytes en su puerto de Arnauld como este:T=a=>{int x=(int)Math.Log(a,2);return(a&=a/2)>0?T(a):x<0?0:x;}
Kevin Cruijssen
1
O incluso dos bytes más guardados ( 60 bytes ):T=a=>(a&a/2)>0?T(a&a/2):Math.Log(a,2)<0?0:(int)Math.Log(a,2)
Kevin Cruijssen
2

Casco , 12 bytes

→S§-€¤≠Lo▲gḋ

Pruébalo en línea!

Explicación

                 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
H.PWiz
fuente
2

Jalea ,  14 13 12  11 bytes

Bµṣ0Ṫ$ƤMḢạL

Un enlace monádico que toma y devuelve enteros no negativos.

Pruébalo en línea! o ver el conjunto de pruebas .

¿Cómo?

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
Jonathan Allan
fuente
Tuve una solución similar pero ŒrṪPen su lugar usé los prefijos.
millas
2

Jalea , 19 bytes

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

Pruébalo en línea!

¡Gracias a Jonathan Allan por guardar  4  6 bytes!

He trabajado demasiado para abandonar esto, aunque es un poco largo. Realmente quería agregar una solución que literalmente busca la subcadena más larga de 1s en la representación binaria ...

Explicación

BŒgḄṀB - Enlace auxiliar monádico. Se utilizará con Ç en el siguiente enlace.

B - Representación binaria.
 Œg - Agrupa ejecuciones de elementos iguales consecutivos.
   Ḅ - Convertir de binario a entero.
    Ṁ - Valor máximo.
     B - Convierte de entero a binario.


BwÇɓÇL + ɓBL_ '- Enlace principal.

B - Representación binaria (de la entrada).
  Ç - Último enlace como mónada. Toma el entero de entrada.
 w - Primer índice de sublista.
   ɓ - Comience una cadena diádica separada. Invierte los argumentos.
    Ç - Último enlace como mónada.
     L - Longitud.
      + - Suma
       ɓ - Comience una cadena diádica separada. Invierte los argumentos.
        B - Binario.
         L - Longitud.
          _ '- Resta e incrementa el resultado (porque Jelly usa indexación 1).
              - Salida implícita.
Sr. Xcoder
fuente
Su enlace de ayuda podría ser BŒgḄṀBen su lugar
Jonathan Allan
@ JonathanAllan Oh wow, gracias!
Sr. Xcoder
Su enlace principal podría serBwÇɓÇL+ɓBL_‘
Jonathan Allan
@ JonathanAllan Wow, gracias de nuevo!
Sr. Xcoder
2

Kotlin , 77 bytes

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

Embellecido

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

Prueba

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}")
}
jrtapsell
fuente
No lo probé, pero creo que esto también funciona en scala.
V. Courtois
2

Haskell , 101 98 96 75 bytes

snd.maximum.(`zip`[0..]).c
c 0=[0]
c n|r<-c$div n 2=sum[r!!0+1|mod n 2>0]:r

Pruébalo en línea! Uso: snd.maximum.(`zip`[0..]).c $ 142rendimientos 1.

Explicación:

  • cconvierte la entrada en binario y, al mismo tiempo, cuenta la longitud de las rayas de una, y recopila los resultados en una lista. r<-c$div n 2calcula recursivamente el resto rde esta lista, mientras sum[r!!0+1|mod n 2>0]:ragrega la longitud actual de la racha r. La comprensión de la lista verifica si mod n 2>0, es decir, si el dígito binario actual es uno, y si es así, toma la longitud de la racha anterior (el primer elemento de r) y agrega uno. De lo contrario, la comprensión de la lista está vacía y sum[]rinde 0. Para la entrada de ejemplo, se c 142obtiene la lista [0,3,2,1,0,0,0,1,0].

  • (`zip`[0..])agrega la posición a cada elemento de la lista anterior como el segundo componente de una tupla. Por el ejemplo esto da [(0,0),(3,1),(2,2),(1,3),(0,4),(0,5),(0,6),(1,7),(0,8)].

  • maximumencuentra la tupla lexicográficamente máxima en esta lista, es decir, las longitudes de las rayas se consideran primero ya que son el primer componente y, en caso de empate, el segundo componente, es decir, el índice más grande, decide. Esto rinde (3,1)en el ejemplo y snddevuelve el segundo componente de la tupla.

Laikoni
fuente
2

C (gcc) , 81 80 bytes

i,l,c,r;f(n){for(i=l=c=r=0;n;n/=2,i++)c=n&1?c+1:c>=l?r=i-(l=c),0:0;n=c<l?r:i-c;}

Pruébalo en línea!

C (gcc) , 43 bytes

Versión de CA de la respuesta de @ Arnauld

k;f(n){n=(k=n&n/2)?f(k):(k=log2(n))<0?0:k;}

Pruébalo en línea!

cleblanc
fuente
Echo de menos el regreso n; o devolver k; declaración
RosLuP
Sugerir en n<1?0:log2(n)lugar de(k=log2(n))<0?0:k
ceilingcat
2

Servidor MS SQL, 437 426 407 398 bytes

Violín de SQL

Estoy seguro de que podría eliminar los saltos de línea, etc., pero esto es tan compacto como estaba dispuesto a hacerlo:

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

Aquí hay una versión más legible:

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

El verdadero truco es que, por lo que pude encontrar, no hay una funcionalidad SQL nativa para convertir un número de decimal a binario. Como resultado, tuve que codificar la conversión a binario manualmente, luego pude comparar eso como una cadena, un carácter a la vez hasta que encontré el número correcto.

Estoy seguro de que hay una mejor manera de hacer esto, pero no vi una respuesta (n) de SQL, así que pensé que lo lanzaría allí.

phroureo
fuente
Si puede jugar más al golf, hágalo. Pero por lo demás, ¡esto es genial! Bienvenido a PPCG!
NoOneIsHere
@NoOneIsHere gracias! Me di cuenta de que también puedo acortar el nombre de mi función;)
phroureo
2

APL (Dyalog Unicode) , 22 caracteres = 53 bytes

Requiere ⎕IO←0cuál es el predeterminado en muchos sistemas.

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

Pruébalo en línea!

 solicitud de entrada

 rendimiento que (se separa ¯1de )

2⊥⍣¯1 convertir a base-2, usando tantas posiciones como sea necesario

b← almacenar como b(para b inary)

 marcha atrás

() Marque las posiciones iniciales de lo siguiente en eso:

⊆⍨b autopartición b(es decir, las 1 rayas de b)

 mezclar (hacer una lista de listas en matriz, relleno con ceros)

∨⌿ reducción vertical O (produce la racha más larga)

d ndices de posiciones iniciales

 marcha atrás

 elija el primero (produce cero si no hay ninguno disponible)

Adán
fuente
que se está perdiendo una ∇ en el pie de página sobre el Tio
NGN
@ngn Tienes razón.
Adám
1

MATL , 15 bytes

`tt2/kZ&t]xBnq&

Pruébalo en línea!

Utiliza la mitad y la idea AND. El ksólo es necesario para que sea interrumpido a causa de 1- por alguna razón, 1 y 0,5 devuelve 1, provocando un bucle infinito.

(solución alternativa: BtnwY'tYswb*&X>)-convirtiendo a codificación binaria y de longitud de ejecución)

B. Mehta
fuente
1

Hojas de cálculo de Google, 94 bytes

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

No, no es muy bonita. Sería realmente bueno poder almacenar Dec2Bin(A1)como una variable de referencia.

Punto clave: al igual que Excel, la Dec2Binfunción tiene un valor de entrada máximo de 511. Cualquier cosa mayor que eso devuelve un error, como se ve a continuación.

Resultados

Tostadas de ingeniero
fuente
1

R, 117 bytes

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))
Zahiro Mor
fuente
104 bytes! En lugar de rev, use Reduce(...,T,T)para acumular desde la derecha (cambiando x,yla definición de la función). Luego, use 1+max(z)-which.max(z)ya que el resultado es algo diferente. Usar en "if"lugar de "ifelse"ya que no necesitamos la vectorización; y si usa en any(z)lugar de !sum(z)soltar un byte.
Giuseppe
Creo que deberíamos poder llevar esto a menos de 100 bytes.
Giuseppe
@giuseppe ¡Me siento un poco tramposo por estar aquí antes que tú! Hará veces tnx un montón!
Zahiro Mor
Pero un buen enfoque no?
Zahiro Mor
1
Oh, no te preocupes, vi esto antes, pero no tenía ganas de responder porque R es muy malo en operaciones de bits ... Sí, buen trabajo, tienes mi +1
Giuseppe
1

Excel VBA, 54 44 Bytes

-10 Bytes gracias a @EngineerToast

Función de ventana inmediata anónima de VBE que toma entrada del rango [A1]y salidas a la ventana inmediata de VBE

?Instr(1,StrReverse([Dec2Bin(A1)]),1)+[A1>0]
Taylor Scott
fuente
1
Además de que la supervisión C1todavía está allí, en lugar de A1, creo que puede generar los Instrresultados directamente con un pequeño giro para la corrección de entrada cero: ?Instr(1,StrReverse([Dec2Bin(A1)]),1)+([A1]>0)(46 bytes). Verdadero = -1 porque ... VBA.
Engineer Toast
@EngineerToast - ¡Dulce! Debería haberlo visto; Pude soltarlo 2 bytes al poner el >0en la [A1]notación
Taylor Scott
0

R, 66 bytes

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

Explicación:

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
        ])
}
Julian Zucker
fuente
1
Esto devuelve la duración de la racha más larga, no su posición. Verifique los casos de prueba y las especificaciones en la parte superior.
user2390246
Cambiaré mi voto a favor negativo una vez que se corrija esta respuesta. Además, tenga en cuenta que puede usar en a$llugar de a[[1]]y en a$vlugar de a[[2]]guardar algunos bytes :), así como en >0lugar de ==1.
Giuseppe
0

Javascript, 54 caracteres

f=i=>i.toString(2).split(0).sort().reverse()[0].length
  • i.toString(2) obtiene la cadena binaria para el entero.
  • los .split(0) obtiene cada parte las secuencial en un elemento de matriz.
  • .sort().reverse() nos da el valor más alto como el primero.
  • El [0].lengthnos da la longitud de ese primer valor.
nl-x
fuente
the starting position of number of largest consecutive 1's
L3viathan
0

Perl 5, 45 + 1 (-p)

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

Si escribe esto en la línea de comando de la mayoría de los shells, puede que tenga que escribir esto como:

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

El baile de las citas al final es solo para que Perl vea a ', que de lo contrario sería consumido por el caparazón.


fuente
0

Retina , 52 43 bytes

Convierta a binario, luego reemplace con la longitud de lo que sigue a la cadena más grande de unos.

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

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

.

Pruébalo en línea : todos los casos de prueba

Guardado 9 bytes gracias a Martin.

mbomb007
fuente
Puedes usar $+para ${1}. Pero puede ahorrar aún más al reemplazar la última etapa con un montón de etapas como esta: tio.run/##K0otycxL/K/…
Martin Ender
@MartinEnder Ok. El ${1}fue copiado de su tutorial en Github.
mbomb007