Revizia anterioară Revizia următoare
Coduri Gray
(Categoria Matematica, autor Cosmin Negruseri)
Introducere
Acest articol prezinta notiunea de Cod Gray si unele aplicatii ale lui in probleme de la concursurile de programare.
Un cod Gray de ordin este un sir care contine toate numerele de la
la
, astfel ca oricare doua numere consecutive din sir difera in reprezentarea binara prin exact un bit. Pentru
exista mai multe coduri Gray distincte. Un cod mai des intalnit, numit in engleza binary reflected Gray code (in continuare cand vom vorbi despre codul Gray ne vom referi de fapt la acest cod). Modul de constructie al acestui cod este unul intuitiv: la fiecare pas adaugam numarul adaugat anterior, caruia ii modificam cel mai putin semnificativ bit, astfel ca numarul obtinut sa nu mai fi fost adaugat inainte la şir. De exemplu, dacă ordinul este doi si avem la inceput numarul
in sir, vom adauga
, apoi
, iar apoi
.
In acest articol vom nota acest cod cu . O alta metoda de constructie care obtine acelasi cod Gray este de a determina mai intai pe
, apoi daca notam cu
sirul
inversat, atunci obtinem pe
daca punem cate un bit de
in fata fiecarui numar din
, iar acestea sunt urmate de numerele din
carora le adaugam cate un bit de
ca bit semnificativ ( pe scurt
(1) ). Observam ca acest cod este unul circular, adica ultimul numar si primul numar din cod difera prin exact un bit. Observam de asemenea ca fiecare cod de ordin
il contine pe cel de
ca prefix, deci am putea nota prin
sirul numerelor naturale in care orice doua numere consecutive difera in reprezentarea binara prin exact un bit si pentru care sirul primelor
elemente coincide cu
, oricare ar fi acest
un numar natural.
Fie al
-lea numar din
(prin
notam codul Gray al numarului
) si
la ce pozitie apare numarul
in sirul
. Ne punem problema calcularii eficiente a celor doua functii. Se poate demonstra prin inductie ca daca avem un numar
cu reprezentarea binara
si codul lui Gray, cu reprezentarea binara
, atunci avem
^
(2). De exemplu, daca avem numarul
cu reprezentarea binara
, atunci
^
^
,
^
^
,
^
^
, deci
. Din aceasta relatie tragem concluzia ca
(unde prin / am notat impartire intreaga). Din (2) obtinem ca
^
^
^
^
^
^
^
^
^
. Aceasta suma este finita deoarece vom avea un
egal cu
si un
egal cu
, daca
este indeajuns de mare. Astfel
^
^
^
Din cele de mai sus obtinem urmatoarele metode:
int binToGray(int x) {
return x ^ (x >> 1);
}
int grayToBin(int y) {
int ret = 0;
while (y > 0) {
ret ^= y;
y >>= 1;
}
return ret;
}
Sa vedem mai departe cateva probleme: