Carel
Carel

Reputation: 3397

Binary string comparison

I'm just learning python and the best way to learn a language is to use it, so I thought I'd make a script that compares binary words to determine which ones are grey.

If there is one bit that is different then it should flag record which number binary code it is. So by means of example, if N=3 then the binary code is 000, 001, 010, 011, 100, 101, 110, 111

If I chose my first binary code as 010 then the code should return 110, 000, 011 as the results, or preferably the indices 0,3,6 (or 1,4,7).

My question is this :

What is the best pythonic way to do this, mostly I'm aiming at the fastest code.

My reason is that some of you would have a better idea on the optimal way to do this and I could then compare my code to that and this would teach me far more.

Upvotes: 2

Views: 11264

Answers (2)

phihag
phihag

Reputation: 287755

Since this is a binary calculation problem (with a weird input), it's not really the area where you can apply pythonic tools like generators, list comprehensions and itertools.

def neighbors(code, N=3):
  num = int(code, 2)
  return [num ^ (1 << (N-i-1)) for i in range(N)]

If you want the output to be sorted (i.e. 0,3,6 instead of 6,0,3), use:

def neighbors_sorted(code, N=3):
  num = int(code, 2)
  return sorted(num ^ (1 << i) for i in range(N))

Upvotes: 2

Carel
Carel

Reputation: 3397

I wanted to post my initial attempt as the first answer but the website blocked me for around 8 hrs, and I've only been able to reply now. I've split the code into the more important snippets.

This is my attempt so far :

I think I should perform the following mods to the code below :

    1) Use dicts so that I have 0:000,1:001,... to improve the indexing.
    2) Take the comparison string, adapt it to a list of all possible options 
       then compare this to the full binary list e.g. 010 becomes 110,000,011 
       and this is then is compared to the full binary list.

My attempt to create a list of binary numbers is as follows (not using dicts yet)

def BinaryNumberList(N=4):
 Bins=[]
 for Num in range(2**N):
 Bin=''
 for Pow in sorted(range(N),reverse=True):
  Bin=Bin+str(Num/(2**Pow))
  Num=Num-Num/(2**Pow)*2**Pow
  Bins.append(Bin)
 return Bins

Then run a for loop for comparing each string to the rest (currently not the best one)

def GreySets(Bins):
 for Bin1 in Bins :
  for Bin2 in Bins :
   stringXOR(Bin1,Bin2)

The string XOR I got from some one elses code on the interwebs and it returns a TrueFalseTrue (I need it to retrun the number of bits that don't match)

def stringXOR(a, b):
 # Error Checking
 msg = "Strings do not have same length: %d, %d!"
 assert len(a) == len(b), msg % (len(a), len(b))
 cnt = len(a) - 1
 # Code
 result = ''
 while cnt + 1:
     result = `(a[cnt] != b[cnt])` + result
     cnt = cnt - 1
 return result

Upvotes: 0

Related Questions