Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Introduction

A Gray Code is an alternative to binary representation in which a number is incremented by toggling only one bit, rather than a variable amount of bits. Here are some gray codes along with their decimal and binary equivalents:

 decimal | binary | gray
-------------------------
       0 |      0 |    0
-------------------------
       1 |      1 |    1
-------------------------
       2 |     10 |   11
-------------------------
       3 |     11 |   10
-------------------------
       4 |    100 |  110
-------------------------
       5 |    101 |  111
-------------------------
       6 |    110 |  101
-------------------------
       7 |    111 |  100
-------------------------
       8 |   1000 | 1100
-------------------------
       9 |   1001 | 1101
-------------------------
      10 |   1010 | 1111
-------------------------
      11 |   1011 | 1110
-------------------------
      12 |   1100 | 1010
-------------------------
      13 |   1101 | 1011
-------------------------
      14 |   1110 | 1001
-------------------------
      15 |   1111 | 1000

Cyclic Bit Pattern of a Gray Code

Sometimes called "reflected binary", the property of changing only one bit at a time is easily achieved with cyclic bit patterns for each column starting from the least significant bit:

bit 0: 0110011001100110011001100110011001100110011001100110011001100110
bit 1: 0011110000111100001111000011110000111100001111000011110000111100
bit 2: 0000111111110000000011111111000000001111111100000000111111110000
bit 3: 0000000011111111111111110000000000000000111111111111111100000000
bit 4: 0000000000000000111111111111111111111111111111110000000000000000
bit 5: 0000000000000000000000000000000011111111111111111111111111111111

...and so on.

Objective

Given a non-padded input string of a gray code, increment the gray code by alternating a single character in the sequence or prepending a 1 (when incrementing to the next power of 2), then output the result as a non-padded gray code.

Caveats

  • Do not worry about taking 0 or an empty string as input.
  • The lowest input will be 1, and there is no upper-bound to the string length other than memory limitations imposed by the environment.
  • By non-padded string, I mean there will be no leading or trailing whitespace (other than an optional trailing newline), and no leading 0s in the input or output.

I/O formats

The following formats are accepted form for input and output, but strings are encouraged over other formats:

  • non-padded character array or string of ASCII '1's and '0's
  • non-padded integer array of 1s and 0s
  • non-padded boolean array

What's not allowed:

  • decimal, binary or unary integer

Tests

input -> output
1 -> 11
11 -> 10
111 -> 101
1011 -> 1001
1111 -> 1110
10111 -> 10110
101100 -> 100100
100000 -> 1100000

More tests can be added by request.

Criteria

This is , so shortest program in bytes wins! All ties will be broken by favoring earlier submissions; standard loopholes apply. The best submitted answer will be accepted October 9th, 2016, and updated whenever better answers are given.

share|improve this question
1  
Related. Related. – Martin Ender 5 hours ago
    
Can we take input as a number? – xnor 5 hours ago
    
Less obviously, also related. – Martin Ender 5 hours ago
    
@xnor No. That sort of defeats the purpose of the string manipulation challenge. – Patrick Roberts 5 hours ago
    
According to your table (and wikipedia) 1011 is incremented to 1001 and not 1010 as in the testcases. – Laikoni 3 hours ago

MATL, 18 bytes

ZBtE:t2/kZ~tb=fQ)B

Try it online! Or verify all test cases.

Explanation

Let a(n) denote the sequence of integers corresponding to Gray codes (OEIS A003188). The program uses the characterization a(n) = n XOR floor(n/2), where XOR is bit-wise.

Essentially, the code converts the input to an integer a0, finds that integer in the sequence, and then selects the next term. This requires generating a sufficiently large number of terms of the sequence a(n). It turns out that 2·a0 is sufficiently large. This stems from the fact that the Gray code a(n) never has more binary digits than n.

Let's take input '101' as an example.

ZB      % Input string implicitly. Convert from binary string to integer
        %   STACK: 5
t       % Duplicate
        %   STACK: 5, 5
E       % Multiply by 2. This is the number of terms we'll generate from the sequence
        %   STACK: 5, 10
:       % Range
        %   STACK: 5, [1 2 3 4 5 6 7 8 9 10]
t       % Duplicate
        %   STACK: 5, [1 2 3 4 5 6 7 8 9 10], [1 2 3 4 5 6 7 8 9 10]
2/k     % Divide by 2 and round down, element-wise
        %   STACK: 5, [1 2 3 4 5 6 7 8 9 10], [0 1 1 2 2 3 3 4 4 5]
Z~      % Bit-wise XOR, element-wise
        %   STACK: 5, [1 3 2 6 7 5 4 12 13 15]
t       % Duplicate
        %   STACK: 5, [1 3 2 6 7 5 4 12 13 15], [1 3 2 6 7 5 4 12 13 15]
b       % Bubble up
        %   STACK: [1 3 2 6 7 5 4 12 13 15], [1 3 2 6 7 5 4 12 13 15], 5
=       % Equality test, element-wise
        %   STACK: [1 3 2 6 7 5 4 12 13 15], [0 0 0 0 0 1 0 0 0 0]
f       % Find: yield (1-based) index of nonzero values (here there's only one)
        %   STACK: [1 3 2 6 7 5 4 12 13 15], 6
Q       % Increase by 1
        %   STACK: [1 3 2 6 7 5 4 12 13 15], 7
)       % Apply as index
        %   STACK: 4
B       % Convert to binary array
        %   STACK: [1 0 0]
        % Implicitly display
share|improve this answer
    
I notice the output is space-delimited characters... is it printing some sort of array? – Patrick Roberts 3 hours ago
    
@PatrickRoberts Yes, exactly. I assumed it's acceptable, is it? – Luis Mendo 3 hours ago
    
I'll accept it as-is. I've already loosened my requirements on I/O format, so there's no point in making it more strict again. Nice job. – Patrick Roberts 3 hours ago

Jelly, 10 8 bytes

Thanks to Dennis for saving 2 bytes.

^\Ḅ‘^H$B

Input and output are lists of 0s and 1s.

Try it online!

Explanation

The inverse of the Gray code is given by A006068. Using this we don't need to generate a large number of Gray codes to look up the input. One classification of this sequence given on OEIS is this:

a(n) = n XOR [n/2] XOR [n/4] XOR [n/8] ...

Where the [] are floor brackets. Consider the example of 44 whose binary representation is 101100. Dividing by 2 and flooring is just a right-shift, chopping off the least-significant bit. So we're trying to XOR the following numbers

1 0 1 1 0 0
  1 0 1 1 0
    1 0 1 1
      1 0 1
        1 0
          1

Notice that the nth column contains the first n bits. Hence, this formula can be computed trivially on the binary input as the cumulative reduction of XOR over the list (which basically applies XOR to each prefix of the list and gives us a list of the results).

This gives us a simple way to invert the Gray code. Afterwards, we just increment the result and convert it back to the Gray code. For the latter step we use the following definition:

a(n) = n XOR floor(n/2)

Thankfully, Jelly seems to floor the inputs automatically when trying to XOR them. Anyway, here is the code:

^\          Cumulative reduce of XOR over the input.
  Ḅ         Convert binary list to integer.
   ‘        Increment.
    ^H$     XOR with half of itself.
       B    Convert integer to binary list.
share|improve this answer
    
You don't need the Ḟ$; bitwise operators cast to int. – Dennis 1 hour ago
    
@Dennis Thanks, I discovered that while writing up. :) – Martin Ender 1 hour ago
    
@MartinEnder Is the integer it converts to internally a big integer? – Patrick Roberts 25 mins ago

Haskell, 118 115 bytes

g 0=[""]
g n|a<-g$n-1=map('0':)a++map('1':)(reverse a)
p=map(snd.span(=='0')).g
f s=(snd.span(/=s)$p$1+length s)!!1

Try it on Ideone.
First approach: Generate the set of all gray codes with length(input)+1, remove all elements until input is found, return the next element.

share|improve this answer
    
Good first answer! I hope we can get some more efficient ones soon. – Patrick Roberts 3 hours ago

JavaScript (ES6), 58 bytes

s=>s.replace(s.split`1`.length%2?/.$/:/.?(?=10*$)/,c=>1-c)

Directly toggles the appropriate bit.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.