f=lambda n,k=1:`k`in bin(n^n/2)and-~f(n,k*10)
Wypróbuj online!
Jak to działa
Przez XORing n i n / 2 (dzielenie przez 2 zasadniczo odcina ostatni bit), otrzymujemy nową liczbę całkowitą m, której nieuzbrojone bity wskazują pasujące sąsiednie bity w n .
Na przykład, jeśli n = 1337371 , mamy następujące.
n = 1337371 = 101000110100000011011₂
n/2 = 668685 = 10100011010000001101₂
m = 1989654 = 111100101110000010110₂
Zmniejsza to zadanie znalezienia najdłuższego ciągu zer. Ponieważ binarna reprezentacja dodatniej liczby całkowitej zawsze zaczyna się od 1 , spróbujemy znaleźć najdłuższy 10 * ciąg cyfr, który pojawia się w binarnej reprezentacji m . Można to zrobić rekurencyjnie.
Zainicjuj k jako 1 . Za każdym razem , gdy wykonuje się f , najpierw sprawdzamy, czy dziesiętna reprezentacja k pojawia się w binarnej reprezentacji m . Jeśli tak, mnożymy k przez 10 i ponownie wywołujemy f . Jeśli nie, kod po prawej stronie and
nie jest wykonywany, a my zwracamy False .
Aby to zrobić, najpierw wykonujemy obliczenia bin(k)[3:]
. W naszym przykładzie bin(k)
zwraca '0b111100101110000010110'
, a 0b1
na początku usuwa się za pomocą [3:]
.
Teraz -~
przed wywołaniem rekurencyjnym inkrementuje wartość False / 0 za każdym razem, gdy f jest wywoływane rekurencyjnie. Gdy 10 {j} ( 1, po których następuje j powtórzeń 0 ) nie pojawia się w binarnej reprezentacji k , najdłuższy ciąg zer w k ma długość j - 1 . Ponieważ J - 1 kolejnymi zerami w k wskazuje J dopasowania sąsiednie bity n pożądany rezultat jest j , która jest co uzyskać zwiększając wartość fałsz / 0w sumie j razy.