f=lambda n,k=1:`k`in bin(n^n/2)and-~f(n,k*10)
Спробуйте в Інтернеті!
Як це працює
За допомогою XORing n і n / 2 (ділення на 2, по суті, відсікає останній біт), ми отримуємо нове ціле число m , невстановлені біти вказують на збіг сусідніх бітів у n .
Наприклад, якщо n = 1337371 , маємо наступне.
n = 1337371 = 101000110100000011011₂
n/2 = 668685 = 10100011010000001101₂
m = 1989654 = 111100101110000010110₂
Це зменшує завдання знайти найдовший пробіг нулів. Оскільки двійкове подання додатного цілого цілого завжди починається з 1 , ми спробуємо знайти найдовший 10 * рядок цифр, який з’являється у двійковому поданні m . Це можна зробити рекурсивно.
Ініціалізуйте k як 1 . Кожен раз, коли виконується f , ми спочатку перевіряємо, чи десяткове подання k з'являється у двійковому поданні m . Якщо це так, множимо k на 10 і знову викликаємо f . Якщо це не так, код праворуч від and
не виконується, і ми повертаємо False .
Для цього спочатку обчислюємо bin(k)[3:]
. У нашому прикладі bin(k)
повертається '0b111100101110000010110'
, а 0b1
на початку видаляється за допомогою [3:]
.
Тепер, -~
перед рекурсивними збільшеннями виклику False / 0 раз на кожен раз, коли f викликається рекурсивно. Коли 10 {j} ( 1 з подальшим j повторенням 0 ) не з’являється у двійковому поданні k , найдовший пробіг нулів у k має довжину j - 1 . Оскільки j - 1 послідовних нулів у k вказують на j, що відповідають сусіднім бітам у n , бажаний результат дорівнює j , який ми отримуємо, збільшуючи False / 0в цілому j разів.