class Solution:
@staticmethod
def minEnd(n: int, x: int) -> int:
return x | sum(((n - 1) >> i & 1) << p for p, i in enumerate(p for p in range(x.bit_length() + (n - 1).bit_length()) if not x & (1 << p)))
ПапаВысший разум (144030)
2 недели назад
Ну это тот же индийский цикл, только вытянутый в одну строчку. Медленно, громоздко. Причём если у меня цикл проходит только по нулевым битам икса, то тут - по всем битам x и по всем битам n-1.
Не, я искал что-то вроде bit_length(), bit_count() и т.п., чтобы можно было одним вызовом сделать депозит битов в нужные позиции, обозначенные маской.
https://leetcode.com/problems/minimum-array-end/description/
Нужно найти минимально возможное n-1-ое число строго возрастающей последовательности положительных чисел, AND всех элементов которой даёт заданное число x. Понятно, что нужно просто биты раскидать в свободные слоты этого самого икса.
Собственно, задача не особо сложная, минут за 15 решается при помощи интринсиков (вообще, за минуту, но не в моём возрасте и не в 4 часа ночи). Пока индийские друзья писали свои любимые циклы, слепил я на эту тему однострочник примерно такого вида: (для C и Rust - аналогично)
Java тоже приятно удивила. Мало того, что нашёлся метод, так он ещё и интринсифицирован в OpenJDK (и их JDK как раз LC и использует):
А вот в Питоне так не получается. Цикл, конечно, работает (медленная ручная реализация PDEP): и даже светит 0 ms / 100% в итогах выполнения.
Но есть ли способ решить это однострочником, без циклов, как в нормальных языках?
А тут - решение со ссылками на код. Всё, кроме Java, исполняется достаточно шустренько:
https://leetcode.com/problems/minimum-array-end/solutions/6024965/bit-deposit-one-liner-beating-100-in-c-c-rust-and-python/