Код Грея
Код Грея — це двійкова система числення, у якій два сусідні значення відрізняються лише в одному біті.
Позначимо через представлення числа у коді Грея. Послідовність кодів Грея для 3-бітових чисел така: 000, 001, 011, 010, 110, 111, 101, 100, тож . Наприклад, і відрізняються рівно в одному біті — найлівішому. Аналогічно, і відрізняються рівно в одному біті — найправішому. Це справджується для всіх послідовних чисел.
Цей код винайшов Frank Gray у 1953 році.
Знаходження коду Грея
Розгляньмо біти числа і біти числа . Зауважимо, що -й біт дорівнює 1 лише тоді, коли -й біт числа дорівнює 1, а -й біт дорівнює 0, або навпаки (-й біт дорівнює 0, а -й біт дорівнює 1). Отже, :
- C++
- Python
- TypeScript
- Go
int g (int n) {
return n ^ (n >> 1);
}
def g(n: int) -> int:
return n ^ (n >> 1)
function g(n: number): number {
return n ^ (n >> 1);
}
func g(n int) int {
return n ^ (n >> 1)
}
Знаходження оберненого коду Грея
Маючи код Грея , відновимо початкове число .
Рухатимемося від старших бітів до молодших (молодший біт має індекс 1, а старший біт — індекс ). Зв'язок між бітами числа і бітами числа :
Найпростіше це записати в коді так:
- C++
- Python
- TypeScript
- Go
int rev_g (int g) {
int n = 0;
for (; g; g >>= 1)
n ^= g;
return n;
}
def rev_g(g: int) -> int:
n = 0
while g:
n ^= g
g >>= 1
return n
function revG(g: number): number {
let n = 0;
for (; g; g >>= 1)
n ^= g;
return n;
}
func revG(g int) int {
n := 0
for ; g != 0; g >>= 1 {
n ^= g
}
return n
}
Практичні застосування
Коди Грея мають кілька корисних застосувань, інколи доволі несподіваних:
-
Код Грея з бітів утворює гамільтонів цикл на гіперкубі, де кожен біт відповідає одному виміру.
-
Коди Грея використовують для мінімізації помилок під час цифро-аналогового перетворення сигналів (наприклад, у сенсорах).
-
Код Грея можна застосувати для розв'язання задачі про Ханойські вежі. Нехай позначає кількість дисків. Почнемо з коду Грея довжини , який складається з самих нулів (), і рухаймося між послідовними кодами Грея (від до ). Нехай -й біт поточного коду Грея відповідає -му диску (молодший біт відповідає найменшому диску, а старший біт — найбільшому). Оскільки на кожному кроці змінюється рівно один біт, ми можемо трактувати зміну -го біта як переміщення -го диска. Зауважимо, що для кожного диска (крім найменшого) на кожному кроці (крім початкової та кінцевої позицій) існує рівно один варіант переміщення. Для найменшого диска завжди є два варіанти переміщення, але існує стратегія, яка завжди приводить до відповіді: якщо непарне, то послідовність переміщень найменшого диска має вигляд (де — початковий стрижень, — кінцевий стрижень, а — стрижень, що залишився), а якщо парне: .
-
Коди Грея також використовують у теорії генетичних алгоритмів.