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 and
non viene eseguito e restituiamo False .
Per fare questo, prima calcoliamo bin(k)[3:]
. Nel nostro esempio, bin(k)
restituisce '0b111100101110000010110'
e 0b1
all'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.