Find twelve 32-bit numbers such that each pair of them differs by bits in at least 17 positions.
I'm struggling to find and optimal algorithm for this problem. More general question is: Find 'n' 32-bit numbers such that each pair of them differs by bits in at least 'm' positions.
My first approach was to randomly pick a number or start from any let's say 6 (00000110) and then once again pick other random number. Then make a XOR operation and count how many 1 we have in binary representation of the XOR result which will indicate on how many places the numbers differentiate. If the condition is accepted we can store those two numbers and do the same process until we reach wanted amount of numbers. However such algorithm seems not to be optimal because we are picking random numbers so it could last 'forever'.
*UPDATE I prepared such code and for m = 16 it actually returns 12 results, however for 17 (which I need) it stops at 9 results and code never finishes. I am wondering if it is possible that in [0, 2^32] range there are not such twelve numbers, but how to prove it?
import random
def hamming_distance(x, y):
dist = 0
# The ^ operator sets to 1 only the bits that are different
val = x ^ y
while val > 0:
# We then count the bit set to 1 using the Peter Wegner way
val = val & (val - 1) # Set to zero val's lowest-order 1
dist += 1
# Return the number of differing bits
return dist
def solution(n = 12, m = 17):
result = [0]
while len(result) < n:
r = random.randint(0,2**32)
if all(hamming_distance(r,el) >= m for el in result):
result.append(r)
print(result)
return result
print(solution())
Choosing a code randomly is good for asymptotic channel capacity, but as the argument below shows, you’re right on the edge of what’s possible. Almost surely, if there is a set of code words, it will have some abstract algebraic logic to it.
(Leaving the write-up below for posterity, but basically I re-derived the Plotkin bound.)
Suppose to the contrary that there exists a set of code words W ⊆ {0, 1}32 such that |W| = 12 and, for all {w, x} ⊆ W, we have d(w, x) ≥ 17, where d denotes the number of positions where its arguments differ (Hamming distance). I claim that
The first term of the right-hand side comes directly from the assumption. The second term arises from a parity argument. Decompose W = E ∪ O where E is the set of code words with even parity and O is the set of code words with odd parity. For all {w, x} ⊆ E, we have d(w, x) ≥ 18, since the distance between two code words of even parity is even. Likewise, for all {w, x} ⊆ O, we have d(w, x) ≥ 18. Hence we have |E| (|E| − 1) + |O| (|O| − 1) ≥ 2·6·5 pairs of minimum distance 18.
Now we apply linear algebra. Let V ⊆ {1, −1}32 be the set of code vectors where we derive a code vector from a code word by replacing each 0 with 1 and each 1 with −1. (The formal element-wise transformation is v[i] = (−1)w[i].) We have
where the first equality comes from relating Hamming distance and dot product, and the rest comes from standard linear algebraic arguments. Double the first inequality and add it to the second:
Hilariously enough, both sides are 12·12·32 = 4608. An argument shaped like this rules out 13 code words.