SUM And XOR
April 1, 2016
I don’t know the origin of it, but today’s exercise must be either a homework problem or an interview question:
Assume there are two positive integers a and b that have sum s and XOR x. Given an s on the range [2, 1012] and x on the range [0, 1012], find a list of possible values of the ordered pairs (a, b). For instance, given s = 9 and x = 5, there are four possible pairs: (2, 7), (7, 2), (3, 6) and (6, 3).
Your task is to write a program that finds the pairs. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.
Actually you only have to loop through the range 0 to s/2 since if (a,b) is a solution, then (b,a) is a solution
Hard to resist a nice bit-twiddling challenge: s and x differ just at positions where there is a carry in from the right, and x tells us where the two numbers differ: if the number are the same at a particular bit position, then there is a carry just if they are both 1, if both 0, there can be no carry. If the digits are different at a given position, then because addition and xor are symmetric, we can have 0 and 1 either way round in the original numbers, regardless of the carries. So, the solutions have a certain number of bits fixed, and we can have all possible combinations of the other bits, so we can just count through those combinations: if a is a possible value, we can find the next possible value by setting all fixed bits to 1, incrementing, then setting the fixed bits back to their correct values. Maybe some code is clearer:
Solutions fast and slow in Racket.
For each x=2^k :
i) a b = a + 2^k
s = a + a + 2^k = 2a + 2^k
a = (s – 2^k)/2
ii) a >= 2^k => b = a – 2^k
s = a + a – 2^k = 2a – 2^k
a = (s + 2^k)/2
This is true for each bit of x => so a = (s +/- all combinations of 2^k of x)/2 or there is no result
//————————————————————————–
#include
//————————————————————————–
int main(int argn, char *argv[]) {
if ( argn != 3 ) {
printf(“usage: %s
\n\n”, argv[0]);return 1; //==========================================================>
}
int s = atoi(argv[1]);
int x = atoi(argv[2]);
printf(“s=%d x=%d\n:\n”, s, x);
int i, j;
int n;
int m;
int b[16];
for ( i = 0, m = 1, n = 0;
i m;
i++, m <<= 1
) {
if ( x & m ) {
b[n] = m;
n++;
}
}
for ( i = 0;
i < (1 << n);
i++
) {
int a = s;
for ( j = 0, m = 1;
j < n;
j++, m <>= 1;
int b = s – a;
if ( (a ^ b) != x ) {
//printf(“a=%d b=%d s=%d x=%d FALSE\n”, a, b, a + b, a ^ b);
printf(“no results (sorry)\n”);
return 1; //========================================================>
}
return 0;
}
@J.Fossy: That looks interesting but it’s all got a bit garbled, you might want to have a look at https://en.support.wordpress.com/code/posting-source-code/
In c#:
JS:
thanks for posting problems, good exercise