I am making a function that takes length:int and distance:int as inputs, and output the largest integer that satisfies the following properties in its binary representation:
It starts with
1, ends with1There are
distance - 1many0between each1Its length is strictly less than
length
It could be implemented as the following:
def repeatdigit(length:int, distance:int) -> int:
result = 0
pointer = 1
for _ in range(1, length, distance):
result |= pointer
pointer <<= distance
return result
For example: repeatdigit(10,3)==0b1001001 , repeatdigit(15,4)=0b1000100010001. I’m only caring about binary because I need to use it as a tool of bit manipulation. In practice, length will be very big, distance ** 2 < length. Assuming the input is valid.
As its name suggested, it is repeating a same pattern over and over.
An explicit formula:
result = (1 << (length+distance-2 - ((length-2) % distance)))//((1 << distance) - 1)
But both algorithm are slow, their time complexity is O(n²), where n = length.
Doing similar things with list only takes O(n). Namely ([1]+[0]*(distance-1)) * ((length-2)//distance) + [1]
(Context: I want to make such an integer so that I don’t need to store 0 and 1 in a very long list as it is space consuming)
How do I make such an integer in O(n)?
nis not the value of length; it's the logarithm oflength(or rather, the logarithm oflength + distance).bitarraypackage.