f=lambda n,k=1:`k`in bin(n^n/2)and-~f(n,k*10)
Essayez-le en ligne!
Comment ça marche
En XORing n et n / 2 (en divisant par 2, on coupe essentiellement le dernier bit), on obtient un nouvel entier m dont les bits non définis indiquent les bits correspondants correspondants dans n .
Par exemple, si n = 1337371 , nous avons ce qui suit.
n = 1337371 = 101000110100000011011₂
n/2 = 668685 = 10100011010000001101₂
m = 1989654 = 111100101110000010110₂
Cela réduit la tâche de trouver la plus longue série de zéros. Comme la représentation binaire d'un entier positif commence toujours par un 1 , nous allons essayer de trouver la chaîne de chiffres la plus longue ( 10 *) qui apparaît dans la représentation binaire de m . Cela peut être fait de manière récursive.
Initialise k comme 1 . Chaque fois que f est exécuté, nous testons d’abord si la représentation décimale de k apparaît dans la représentation binaire de m . Si c'est le cas, on multiplie k par 10 et on appelle à nouveau f . Si ce n'est pas le cas, le code à droite de and
n'est pas exécuté et nous renvoyons False .
Pour ce faire, nous calculons d’abord bin(k)[3:]
. Dans notre exemple, bin(k)
retourne '0b111100101110000010110'
et 0b1
le début est supprimé avec [3:]
.
Maintenant, l' -~
appel avant l'appel récursif incrémente Faux / 0 une fois pour chaque fois que f est appelé de manière récursive. Lorsque 10 {j} ( 1 suivi de j répétitions de 0 ) n'apparaît pas dans la représentation binaire de k , la plus longue série de zéros de k a une longueur de j - 1 . Puisque j - 1 zéros consécutifs dans k indiquent j correspondant à des bits adjacents dans n , le résultat souhaité est j , ce que nous obtenons en incrémentant Faux / 0.un total de j fois.