Ternary number n is converted into ternary Gray code a(n) by using the following algorithm: Leftmost term (i.e., digit) is leftmost Gray code term. Then going to the right, if next term b is greater than current term a, then (b - a) is the next Gray code term. (Gray code terms do not enter into the algorithmic operation). If next term b < a, then add 3 to b and perform [(3+b) - a] which becomes the next Gray code term. If b = a, the Gray code term = 0.
Interpreting any N-Ary code for n as N-Ary Gray code or vice versa results in a permutation of the natural numbers. Any N-Ary term can be converted to the N-Ary Gray code by using a generalization of the algorithmic rules such that if b < a, then add N to b and perform [(N + b) - a]. The other rules remain the same.
Martin Cohn, Affine m-ary Gray Codes, Information and Control, volume 6, 1963, pages 70-78. (For the case m=3, U = P = identity matrix, v = 0 vector.)
Donald E. Knuth, The Art of Computer Programming, Pre-Fascicle 2A, Draft of Section 7.2.1.1. See subsection "Nonbinary Gray codes" page 18, and exercise 78 page 35 and answer page 54 (modular Gray g overline for the case all m_j=3).
Joseph Rosenbaum, Elementary Problem E319, American Mathematical Monthly, volume 45, number 10, December 1938, pages 694-696. (For p=3, stepping though switch position combinations by single changes.)
gray := proc(inp::integer, bas::integer) local resul, digs, convdigs, compl, d ; digs := [op(convert(inp, base, bas)), 0] ; convdigs := [] ; for d from 1 to nops(digs)-1 do compl := op(d, digs)-op(d+1, digs) : if compl >= 0 then convdigs := [op(convdigs), compl] ; else convdigs := [op(convdigs), bas+compl] ; fi : od : convdigs := [op(convdigs), op(-1, digs)] : resul := 0 : for d from nops(convdigs) to 1 by -1 do resul := resul*bas + op(d, convdigs) : od : RETURN(resul) ; end: for n from 0 to 50 do printf("%a, ", gray(n, 3)) ; od : # R. J. Mathar, Mar 28 2006