f=lambda n,k=1:`k`in bin(n^n/2)and-~f(n,k*10)
Pruébalo en línea!
Cómo funciona
Al XORing n y n / 2 (dividiendo por 2 esencialmente corta el último bit), obtenemos un nuevo entero m cuyos bits sin establecer indican bits adyacentes coincidentes en n .
Por ejemplo, si n = 1337371 , tenemos lo siguiente.
n = 1337371 = 101000110100000011011₂
n/2 = 668685 = 10100011010000001101₂
m = 1989654 = 111100101110000010110₂
Esto reduce la tarea de encontrar la ejecución más larga de ceros. Dado que la representación binaria de un entero positivo siempre comienza con un 1 , trataremos de encontrar la cadena de dígitos 10 * más larga que aparece en la representación binaria de m . Esto se puede hacer de forma recursiva.
Inicialice k como 1 . Cada vez que se ejecuta f , primero probamos si la representación decimal de k aparece en la representación binaria de m . Si lo hace, multiplicamos k por 10 y llamamos a f nuevamente. Si no lo hace, el código a la derecha de and
no se ejecuta y devolvemos False .
Para hacer esto, primero calculamos bin(k)[3:]
. En nuestro ejemplo, bin(k)
devuelve '0b111100101110000010110'
, y 0b1
al principio se elimina con [3:]
.
Ahora, -~
antes de que la llamada recursiva incremente False / 0 una vez por cada vez que f se llama recursivamente. Una vez que 10 {j} ( 1 seguido de j repeticiones de 0 ) no aparece en la representación binaria de k , la ejecución más larga de ceros en k tiene longitud j - 1 . Como j - 1 ceros consecutivos en k indican j que coinciden con los bits adyacentes en n , el resultado deseado es j , que es lo que obtenemos al incrementar Falso / 0un total de j veces.