-1

I was presented with the following problem: given s and x, compute the number of solutions (a,b) that satisfy both 1) s = a + b, and 2) x = a XOR b. All quantities and operations are integer.

Example Inputs:
    s = 10
    x = 4
Output:
    2

No modules can be imported.

I wrote the following answers which all took too long:

First:

def answer(s,x):
    tally = 0
    z = 0
    while z <= s:
        p = s - z
        q = int(z ^ p)
        if x == q:
            tally += 1
        z += 1
    return tally

Second:

def answer(s,x):
    spotlist, forwardlist = range(0,s+1)
    backwardlist = range(s,-1,-1)
    tally = 0
    for spot in spotlist:
        if x == forwardlist[spot] ^ backwardlist[spot]:
            if s == forwardlist[spot] + backwardlist[spot]:
                tally +=1
    print tally

Third:

def answer(s,x):
    tally = 0
    z = 0
    while z <= s:
        q = int(z ^ (s - z))
        if x == q:
            tally += 1
        else:
            pass
        z += 1
    print tally

I think I'm missing something or iterating through the numbers before removing certain possible solutions.

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
avelardi
  • 13
  • 4
  • 2
    You seem to have left out a crucial part of the problem. You haven't said why you are iterating. It sounds like the problem is not what you said, but you are supposed to consider some range of values. What is the source of this problem? – Douglas Zare Apr 19 '15 at 14:15
  • 2
    possible duplicate of [Given XOR & SUM of two numbers. How to find the numbers?](http://stackoverflow.com/questions/18732329/given-xor-sum-of-two-numbers-how-to-find-the-numbers) – wldsvc Apr 19 '15 at 14:16
  • @thebjorn has an [optimized solution to adding problems](http://stackoverflow.com/questions/11792708/generate-all-possible-combinations-from-a-int-list-under-a-limit); pay attention to the use of sets, caching, and prevention of extra look-ups: see the duplicate for reasons that SUM and XOR cannot be done for all values – LinkBerest Apr 19 '15 at 14:16
  • 2
    I made an extensive edit to the problem statement because I found the original confusing. Someone should double-check it though. – President James K. Polk Apr 19 '15 at 14:20
  • What kind of "integer" are you considering? If it's a wrapping integer with a fixed number of bits, then iff (a,b) is a solution, (a^signbit,b^signbit) is also. – harold Apr 20 '15 at 09:20

1 Answers1

1

If (a, b) is a solution pair, then so is (b, a), so you can reduce the range you test by half. Also, you can take advantage of the fact that if x = a ^ b then b = x ^ a

The code below is more than twice as fast as your first answer() function
with s, x = 10, 4, and more than 4 times faster with s, x = 255, 255.

def xorsum(s, x):
    tally = 0
    for a in xrange(s//2 + 1):
        tally += s - a == x ^ a 
    return 2 * tally

This function uses the fact that Python's False and True have numerical values of 0 and 1, respectively. Doing it like this is faster than using an if test and only incrementing tally if the test is true.


You could implement xorsum using a list comprehension:

def xorsum_lc(s, x):
    return 2 * sum([s - a == x ^ a for a in xrange(s//2 + 1)])

but it's slower than the above function; the equivalent generator expression is even slower (as expected).

PM 2Ring
  • 54,345
  • 6
  • 82
  • 182
  • I should have been much more specific when asking this. Thank you for the above code, it sped up my processing time significantly. – avelardi Apr 20 '15 at 15:16