Reputation: 31
Given four integers a ≤ b ≤ c and k, how do you count integers in [a, c] whose binary representations differ in exactly k positions from that of b? a, b and c are about 30 bits long.
Upvotes: 3
Views: 296
Reputation: 10323
If you need to compute the count for a given a, b and c, and for all values of k, then I think your best bet is to iterate and count the number of bits in the xor'ed difference.
for (int i = a; i <= c; i++) {
int d = i ^ b;
int k = 0;
while (d != 0) {
k++;
d &= (d - 1);
}
counts[k]++;
}
You can even parallellize this easily. You would need to keep a separate set of counts for each thread, and add them all up at the end to get the grand totals.
For a range of 1 billion numbers, the parallel version of this algorithm took 3.7 seconds on my machine.
EDIT: Actually, there is a way to get the counts without enumerating. Here's the basic idea for (a,b,c)=(17,25,29), or in binary (10001,11001,11101). First, notice that the range 11000-11011 contains b, and is also entirely contained in (a,c). So these 2^2 values, contribute choose(2,k) to each count. The next interval down is 10100-10111. The numbers in this range all have at least 2 bits different from b, so they contribute choose(2,k-2) to the kth count. The next interval down that is fully contained in (a,c) is 10010-10011, which contributes choose(1,k-1), and so on. You also have to count upwards.
2nd edit: Couldn't resist implementing this. Total time for 1 billion numbers: 0.004ms...
Upvotes: 1
Reputation: 93040
The total count of numbers which differ in exactly k positions from b and are written with at most 30 bits is binomial(30, k)
. This number is the greatest when k = 15 and is binomial(30, 15) = 155117520
, so this is better then enumarating from a to c, but still can be a lot. However if k is small that's the way - just enumerate all these numbers that differ in exactly k bits and check whether they are between a and c.
If that's too slow, then you should do it more intelligently - for example if a and c have the same highest bit, then this bit has to be set, so you can reduce the possibiities.
Upvotes: 0
Reputation: 26271
Why not just explicitly enumerate all values between a
and c
, checking how many bits differ for each value? The technical term for this in information theory is Hamming distance
http://en.wikipedia.org/wiki/Hamming_distance
Upvotes: 1
Reputation: 135
Write the binary repr for b, flip k of the bits and check if it violates the bounds. For a,b being 30 bits it shouldn't be prohibitive to write a shell script or a C program so long as k is reasonable.
Upvotes: 0