HackerRank bitwiseAnd challenge - algorithm is too slow?

Your algorithm has a brute force approach, but it can be done more efficiently.

First, observe some properties of this problem:

  • 𝐴 & 𝐵 will never be greater than 𝐴 nor than 𝐵
  • If we think we have a solution 𝐶, then both 𝐴 and 𝐵 should have the same 1-bits as 𝐶 has, including possibly a few more.
  • We want 𝐴 and 𝐵 to not be greater than needed, since they need to be not greater than 𝑁, so given the previous point, we should let 𝐴 be equal to 𝐶, and let 𝐵 just have one 1-bit more than 𝐴 (since it should be a different number).
  • The least possible value for 𝐵 is then to set a 1-bit at the least bit in 𝐴 that is still 0.
  • If this 𝐵 is still not greater than 𝑁, then we can conclude that 𝐶 is a solution.
  • With the above steps in mind, it makes sense to first try with the greatest 𝐶 possible, i.e. 𝐶=𝐾−1, and then reduce 𝐶 until the above routine finds a 𝐵 that is not greater than 𝑁.

Here is the code for that:

def bitwiseAnd(N, K):
    for A in range(K - 1, 0, -1):
        # Find the least bit that has a zero in this number A:
        #    Use some "magic" to get the number with just one 1-bit in that position
        bit = (A + 1) & -(A + 1)
        B = A + bit
        if B <= N:
            # We know that A & B == B here, so just return A
            return A  
    return 0