Gray Code

The most widely used version of the Gray code is a bijection ω \omega of the binary representation of the contiguous set of integers [ [ 0 ; n ] ] [\![0;n]\!] such that the binary representations ω ( i ) \omega(i) and ω ( i + 1 ) \omega(i+1) only differ by one bit 0 i < n \forall\ 0\leq i < n .

For example, with n = 7 n=7 , we can choose ω : { 000 , 001 , 010 , 011 , 100 , 101 , 110 , 111 } { 000 , 010 , 011 , 001 , 101 , 100 , 110 , 111 } . \omega : \{000,001,010,011,100,101,110,111\} \mapsto\{000,010,011,001,101,100,110,111\}. How many such bijections ω \omega of [ [ 0 ; 15 ] ] [\![0;15]\!] are there?

Clarification : We don't need the bijections to be cyclic i.e. we can have bijections for which the binary representations ω ( 0 ) \omega(0) and ω ( 15 ) \omega(15) differ by more than one bit (as in the provided example above.)


The answer is 91392.

This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try refreshing the page, (b) enabling javascript if it is disabled on your browser and, finally, (c) loading the non-javascript version of this page . We're sorry about the hassle.

3 solutions

Romain Bouchard
Feb 20, 2018

We can imagine the binary representations of integer 0 0 through 15 15 ( 0000 , 0001 , , 1111 0000,0001,\cdots,1111 ) as the coordinates of a unit hypercube (of dimension 4 4 ).

That way, a Gray code is a Hamiltonian path on this hypercube. Here is a bit of code to compute the total number of paths on the hypercube :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def CountGray(n):
    def Recurse(unused, lastVal, nextSet):
        count = 0
        for changedBit in range(0, min(nextSet + 1, n)):
            newVal = lastVal ^ (1 << changedBit)
            mask = 1 << newVal
            if unused & mask:
                if unused == mask: count += 1
                else: count += Recurse(unused & ~mask, newVal, 
                                               max(nextSet, changedBit + 1))
        return count
    count = Recurse((1 << (1 << n)) - 2, 0, 0)
    for i in range(1, n + 1): count *= 2 * i
    return max(1, count) 
print CountGray(4)

From the wording of the question, it was not obvious what were the permissible starting values for the sequence. My method is is quite similar to Romain Bouchard's in concept and quite different in implementation. n = 4 ; flip = Table [ 2 i , { i , 0 , 3 } ] ; chain = list , Block [ { last , bit , test } , If [ Length [ list ] = 16 , Sow [ list ] ; Return [ ] ] ; last = Last [ list ] ; Do [ test = BitXor [ bit , last ] ; If [ ¬ MemberQ [ list , test ] , chain ( Append [ list , test ] ) ] ; , { bit , flip } ] ; ] ] ; result = Reap [ chain ( { 0 } ) ; ] n=4; \\ \text{flip}=\text{Table}\left[2^i,\{i,0,3\}\right]; \\ \text{chain}=\text{list}, \\ \text{Block}[ \\ \{\text{last},\text{bit},\text{test}\}, \\ \text{If}[\text{Length}[\text{list}]=16,\text{Sow}[\text{list}];\text{Return}[]]; \\ \text{last}=\text{Last}[\text{list}]; \\ \text{Do}[ \\ \text{test}=\text{BitXor}[\text{bit},\text{last}]; \\ \text{If}[\neg \text{MemberQ}[\text{list},\text{test}],\text{chain}(\text{Append}[\text{list},\text{test}])];, \\ \{\text{bit},\text{flip}\}]; \\ ] \\ ]; \\ \text{result}=\text{Reap}[\text{chain}(\{0\});]

This returned a 5712 row 16 column matrix. When 5712 did not work, 16 times that worked.

Dmitriy Khripkov
Feb 20, 2018

Fun problem. For the example shown, though, shouldn't 010 be the first element? The hamming distance between 001 and 010 is 2.

Thanks. I fixed it.

Romain Bouchard - 3 years, 3 months ago

0 pending reports

×

Problem Loading...

Note Loading...

Set Loading...