Gray code
Karnaugh maps
Create functions to encode a number to and decode a number from Gray code.

Display the normal binary representations, Gray code representations, and decoded Gray code values for all 5-bit binary numbers (0-31 inclusive, leading 0's not necessary).

There are many possible Gray codes. The following encodes what is called "binary reflected Gray code."

Encoding (MSB is bit 0, b is binary, g is Gray code):

if b[i-1] = 1
   g[i] = not b[i]
else
   g[i] = b[i]
Or:

g = b xor (b logically right shifted 1 time)
Decoding (MSB is bit 0, b is binary, g is Gray code):

b[0] = g[0]

for other bits:
b[i] = g[i] xor b[i-1]
Reference
 Converting Between Gray and Binary Codes. It includes step-by-step animations.
implement Gray;
 
include "sys.m"; sys: Sys;
	print: import sys;
include "draw.m";
 
Gray: module {
	init: fn(nil: ref Draw->Context, args: list of string);
	# Export gray and grayinv so that this module can be used as either a
	# standalone program or as a library:
	gray: fn(n: int): int;
	grayinv: fn(n: int): int;
};
 
init(nil: ref Draw->Context, args: list of string)
{
	sys = load Sys Sys->PATH;
	for(i := 0; i < 32; i++) {
		g := gray(i);
		f := grayinv(g);
		print("%2d  %5s  %2d  %5s  %5s  %2d\n", i, binstr(i), g, binstr(g), binstr(f), f);
	}
}
 
gray(n: int): int
{
	return n ^ (n >> 1);
}
 
grayinv(n: int): int
{
	r := 0;
	while(n) {
		r ^= n;
		n >>= 1;
	}
	return r;
}
 
binstr(n: int): string
{
	if(!n)
		return "0";
	s := "";
	while(n) {
		s = (string (n&1)) + s;
		n >>= 1;
	}
	return s;
}