The problem is how to invert alternate bits of a number, starting from the LSB. Currently what I am doing is first doing a
count = -1
while n:
n >>= 1
count += 1
to first find the position of the leftmost set bit, then running a loop to invert every alternate bit:
i = 0
while i <= count:
num ^= 1<<i
i += 2
Is there a quick hack solution instead of this rather boring loop solution? Of course, the solution can’t make any asumption about the size of the integer.
The previous one-liner solution,
is an O(lg n) solution, where n is the input number. The asymptotically-much-faster solution shown below runs in time O(lg(lg n)), that is, in time proportional to the log of the number of bits in the input number. Note, the binary search as shown worked ok in tests, but perhaps can be improved.
Edit: The expression
-1<<Lis a mask with its high bits set and its L low bits clear. For example, python displays 255 as the value of(-1<<8)&255, and 256 as the value of(-1<<8)&256. The program begins by doubling L (leaving more and more low bits clear) until L exceeds the number of bits in the number v; that is, until(-1<<L)&vis zero. At each doubling of L, it can move R up. The program then uses binary search, repeatedly halving the L-R difference, to find L=R+1 such thatv&(-1<<L) == 0andv&(-1<<R) > 0, to establish that v is L bits long.Later, the program doubles the length of an alternating-bits mask k until it is at least L bits long. Then it shifts the mask by one bit if L is odd. (Instead of
if L & 1: k = k<<1it could sayk <<= L&1. Note, I interpreted “alternate bits” as beginning with the bit just below the MSB. To instead always toggle bits 0,2,4…, remove theif L & 1: k = k<<1line.) Then it picks off the low L bits of k by &’ing with(1<<L)-1, ie, with (2**L)-1. Note, the program’s O(lg(lg n)) time bound depends on O(1) logical operations; but as L gets large (beyond a few hundred bits),1<<Letc become O(lg n) operations.The output from the four function calls is shown below.