Gray code is a form of binary encoding where transitions between consecutive numbers differ by only one bit. This is a useful encoding for reducing hardware data hazards with values that change rapidly and/or connect to slower hardware as inputs. It is also useful for generating inputs for Karnaugh maps.

Here is an exemple of what the code look like:

```
0:    0000
1:    0001
2:    0011
3:    0010
4:    0110
5:    0111
6:    0101
7:    0100
8:    1100
```

The goal of this kata is to build two function bin2gray and gray2bin wich will convert natural binary to Gray Code and vice-versa. We will use the "binary reflected Gray code". The input and output will be arrays of 0 and 1, MSB at index 0.

There are "simple" formula to implement these functions. It is a very interesting exercise to find them by yourself.

All input will be correct binary arrays.

Difficulty: EASY

Starter code:
def bin2gray(bits):
	

Solutions:
def bin2gray(bits):
	bits.reverse()
	return list(reversed([x if i >= len(bits) - 1 or bits[i + 1] == 0 else 1 - x for (i, x) in enumerate(bits)]))

def gray2bin(bits):
	for (i, x) in enumerate(bits):
		if i > 0 and bits[i - 1] != 0:
			bits[i] = 1 - x
	return bits


def bitlist(func):

	def wrapper(bits):
		i = int(''.join([str(b) for b in bits]), 2)
		result = func(i)
		return [int(b) for b in bin(result)[2:]]
	return wrapper

@bitlist
def bin2gray(bits):
	return bits >> 1 ^ bits

@bitlist
def gray2bin(bits):
	mask = bits >> 1
	while mask != 0:
		bits ^= mask
		mask >>= 1
	return bits


def bin2gray(bits):
	return [1 - x if i and bits[i - 1] else x for (i, x) in enumerate(bits)]

def gray2bin(bits):
	(result, memo) = ([], bits[0])
	for (i, x) in enumerate(bits):
		if i and x:
			result.append(1 - memo)
		else:
			result.append(memo)
		memo = result[-1]
	return result


bin2gray = lambda b: [b[0]] + [b[i + 1] ^ j for (i, j) in enumerate(b[:-1])]

def gray2bin(g):
	b = [g[0]]
	for i in g[1:]:
		b.append(b[-1] ^ i)
	return b


def bin2gray(bits):
	return bits[:1] + [b1 ^ b2 for (b1, b2) in zip(bits, bits[1:])]

def gray2bin(bits):
	return [reduce(lambda x, y: x ^ y, bits[:i + 1], 0) for i in range(len(bits))]


def bin2gray(bits):
	gray = []
	gray.append(bits[0])
	for index in range(1, len(bits), 1):
		gray.append(bits[index - 1] ^ bits[index])
	return gray

def gray2bin(bits):
	bin = []
	bin.append(bits[0])
	for index in range(1, len(bits), 1):
		bin.append(bin[index - 1] ^ bits[index])
	return bin


def bin2gray(bits):
	return [x ^ y for (x, y) in zip(bits, [0] + bits)]

def gray2bin(bits):
	return [reduce(lambda x, y: x ^ y, bits[:i + 1]) for (i, _) in enumerate(bits)]


def bin2gray(bits):
	g = [bits[0]] * len(bits)
	for i in range(1, len(bits)):
		g[i] = bits[i] ^ bits[i - 1]
	return g

def gray2bin(bits):
	b = [bits[0]] * len(bits)
	for i in range(1, len(bits)):
		b[i] = bits[i] ^ b[i - 1]
	return b


def i2l(i):
	l = []
	while i != 0:
		l.append(i % 2)
		i >>= 1
	l.reverse()
	return l if l else [0]

def l2i(l):
	i = 0
	for b in l:
		i = i * 2 + b
	return i

def bin2gray(bits):
	bits = l2i(bits)
	return i2l(bits ^ bits >> 1)

def gray2bin(bits):
	bits = l2i(bits)
	m = bits >> 1
	while m:
		bits = bits ^ m
		m >>= 1
	return i2l(bits)