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 and
não é executado e retornamos False .
Para fazer isso, primeiro calculamos bin(k)[3:]
. Em nosso exemplo, bin(k)
retorna '0b111100101110000010110'
, e o 0b1
no 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.