"""Algorithms which are related to US-American researcher Frank Gray."""
__all__ = ("reflected_binary_code",)
[docs]def reflected_binary_code(
length: int, modulus: int
) -> tuple[tuple[int, ...], ...]:
"""Make gray code where each tuple has `length` items with `modulus` different numbers.
:param length: how long one code is
:param modulus: how many different numbers are included
**Example:**
>>> from mutwo.generators import gray
>>> gray.reflected_binary_code(2, 2)
((0, 0), (0, 1), (1, 1), (1, 0))
>>> gray.reflected_binary_code(3, 2)
((0, 0, 0),
(0, 0, 1),
(0, 1, 1),
(0, 1, 0),
(1, 1, 0),
(1, 1, 1),
(1, 0, 1),
(1, 0, 0))
>>> gray.reflected_binary_code(2, 3)
((0, 0), (0, 1), (0, 2), (1, 2), (1, 1), (1, 0), (2, 0), (2, 1), (2, 2))
Basic code has been copied from:
https://yetalengthothermodulusathblog.com/tag/gray-codes/
"""
def _recursive_gray_code_maker(
length: int, modulus: int
) -> list[list[int]]:
F = range(modulus)
if length == 1:
return [[i] for i in F]
L = _recursive_gray_code_maker(length - 1, modulus)
M: list[list[int]] = []
for j in F:
M = M + [ll + [j] for ll in L]
k = len(M)
Mr: list[list[list[int]]] = [[]] * modulus
for i in range(modulus - 1):
i1 = i * int(k / modulus)
i2 = (i + 1) * int(k / modulus)
Mr[i] = M[i1:i2]
Mr[modulus - 1] = M[(modulus - 1) * int(k / modulus) :] # type: ignore
for i in range(modulus):
if i % 2 != 0:
Mr[i].reverse()
M0: list[list[int]] = []
for i in range(modulus):
M0 = M0 + Mr[i]
return M0
return tuple(
tuple(reversed(list_)) for list_ in _recursive_gray_code_maker(length, modulus)
)