It is a bit like the “Nerds, Jocks and Lockers” problem in terms of “flipping bits,” leaving certain bits to set, while others are not.
The main behavior is that A XOR B works like "(A OR B) AND NOT (A AND B)". So, 0 ^ 0 = 0, 1 ^ 0 = 1, but 1 ^ 1 = 0 (unlike OR). Now you start from zero (without bits) on K. Then you XOR this with the letter 3, which (as a byte) has bits 00000011 and assigns the result K. You end up getting 00000011 for K, because the bits that are set to literal 3, everyone is not set to K when it is 0. Now, if you again had to XOR K with literal 3, you will get 0 because all bits match between the two values, so XOR will return 0 for every bit.
This process is commutative, therefore (((((XOR 3) XOR 6) XOR 3) XOR 6) gives the same result (0) as ((((0 XOR 6) XOR 6) XOR 3) XOR 3), or almost any other combination of XORing 0 with 3 twice and 6 twice.
The end result is that, given the list of these numbers, any number that occurs twice (or an even number of times), first “XORed in” to K, and then “XORed out” the second, leaving K with its bits set to one a meaning that only once happened; 12.
Here is a twofold demonstration of the complete problem (using "nibbles" because we have no values greater than 16):
0000 0 ^^^^ XOR 0011 3 ---- = 0011 3 ^^^^ XOR 0110 6 ---- = 0101 5 ^^^^ XOR 1001 9 ---- = 1100 12 ^^^^ XOR 1100 12 ---- = 0000 0 <-this is coincidence; it'd work the same regardless of the unduped value ^^^^ XOR 0011 3 ---- = 0011 3 ^^^^ XOR 0110 6 ---- = 0101 5 ^^^^ XOR 1001 9 ---- = 1100 12 <- QED
EDIT FROM COMMENTS:. Although this answer works for the specific question asked, even the smallest change in the problem will lead to a "violation" of this implementation, for example:
- The algorithm does not completely correspond to a zero number ; thus, the algorithm cannot determine the difference between a null value as the only unpaired value and no unpaired values at all.
- The algorithm works only for pairs, not for triplets . If 3 happened three times and was still a "trick", and 12 was still the correct answer, this algorithm would actually return 15 (1100 ^ 0011 == 1111), which are not even on the list.
- The algorithm only works if there is only one non-duplicated value in the list ; if 8 and 12 were both unpaired values that are expected to be returned, the algorithm will return an XOR of two (1100 ^ 1000 == 0100 == 4)
An efficient algorithm could be developed that would return the correct answer in all these cases in addition to the original case, but most likely it would not include XOR.