Gray Codes with Constant Delay
and Constant Auxiliary Space
Abstract
We give the first two algorithms to enumerate all binary words of (like Gray codes) while ensuring that the delay and the auxiliary space is independent from , i.e., constant time for each word, and constant memory in addition to the bits storing the current word. Our algorithms are given in two new computational models: tape machines and deque machines. We also study more restricted models, queue machines and stack machines, and show that they cannot enumerate all binary words with constant auxiliary space, even with unrestricted delay.
A tape machine is a Turing machine that stores the current binary word on a single working tape of length (which never increases), using no other tape. The machine has a single head and must edit its tape to reach all possible words of , and output them (in unit time, by entering special output states), with no duplicates. Hence a tape machine uses constant auxiliary space by definition (up to the head position). We construct a tape machine that achieves this task with constant delay between consecutive outputs, so that the machine implements a so-called skew-tolerant quasi-Gray code. We then construct a more involved tape machine that implements a Gray code.
A deque machine stores the current binary word on a double-ended queue of length , and stores a constant-size internal state. It works as a tape machine, except that it modifies the content of the deque by performing push and pop operations on the endpoints. Hence again a deque machine uses constant auxiliary space by definition. We construct deque machines that enumerate all words of with constant-delay. The main technical challenge in this model is to correctly detect when enumeration has finished.
Keywords and phrases:
Gray code, Constant delay, Constant auxiliary space, Enumeration algorithms, Linear bounded automata, Tape machine, Deque machines, Counter implementationCategory:
Track B: Automata, Logic, Semantics, and Theory of ProgrammingCopyright and License:
Yann Strozecki; licensed under Creative Commons License CC-BY 4.0
2012 ACM Subject Classification:
Mathematics of computing EnumerationSupplementary Material:
Software (Gitlab Repository): https://gitlab.com/marsault/constant-delay-gray-code-public/ [2]archived at
swh:1:dir:518eefd91b684efee432607dc091c3d0a10711f9
Acknowledgements:
We are grateful to Gabriel Bathie and Florent Capelli for their insights in discussions about the problem. We also thank Thomas Colcombet and IRIF for their support.Editors:
Sayan Bhattacharya, Danupon Nanongkai, Michael Benedikt, and Gabriele PuppisSeries and Publisher:
Leibniz International Proceedings in Informatics, Schloss Dagstuhl – Leibniz-Zentrum für Informatik
1 Introduction
In this paper we propose new efficient algorithms to produce all binary words of a certain length , i.e., all words of . Specifically, we are looking for efficient enumeration algorithms, which produce these words one after another, without repetitions, and while minimizing the delay between two consecutively produced words. If we require each word to be written from scratch, then obviously we cannot hope for a better delay than . For this reason, we adopt the “Do not count the output” principle from the enumeration algorithms literature [24, p. 8], in the spirit of combinatorial Gray codes [26, 20]. In this setting, a single word is explicitly maintained in memory, the algorithm has an instruction that produces the current word in unit time, and the word can be modified in-place with a certain set of edit operations, before calling the next instruction. Of course, what can be achieved depends on which update operations are allowed. Two common choices are substitutions (i.e., store the current word in an array and make it possible to change the -th symbol) and endpoint modifications (i.e., store the current word in a doubly-linked list and make it possible to push or pop on the endpoints).
In this model, for each set of allowed edit operations, we can try to optimize two things: running time, and memory usage. For running time, the best possible goal is to achieve constant delay, i.e., the number of computation steps and edits from one word produced to the next is bounded by a constant (independent from the word length ). For memory usage, the best possible goal is to achieve constant additional memory, i.e., the memory state consists of the currently produced word (i.e., bits) plus a finite state which is again independent from the word length .
For the more commonly studied setting of substitution updates, it is already known that each of these two aspects can be optimized in isolation. We can achieve constant delay using, for instance, the Binary Reflected Gray Code (BRGC) [22]: start from the word , flip the rightmost bit on odd steps, and flip the bit that is to the left of the rightmost on even steps. This gives what is known in this line of work as a loopless or loop-free algorithm [13]. However, this algorithm requires non-constant additional memory: to quickly find the bit to flip on even steps, we would typically use a linear-sized stack storing the current positions of the ’s; see also [5, 22]. As for constant additional memory, the optimal memory required to implement Gray codes has been studied in the decision assignment tree (DAT) model or bit-probe model [16, 6, 7, 22, 23], with essentially a logarithmic lower bound. However, these models are non-uniform: they assume that the algorithm can freely access the entire word and that it can perform arbitrary computations with possibly high running time as a function of the word length.
For the setting of endpoint modifications, the situation is far more open. There are known related constructions to enumerate binary words, e.g., universal words [10] or Hamiltonian paths in so-called Shuffle Exchange networks [15], but to our knowledge they do not give favorable bounds on the delay and memory usage of an algorithm. We also note that an efficient algorithm has recently been proposed for the so-called Sigma-Tau problem [27, 19]. This problem consists in enumerating all permutations of using specific endpoint modification operations, and as far as we can tell this is a different problem from ours.
Hence, our focus in this work is whether we can achieve the two requirements simultaneously: Can we enumerate with an algorithm that uses only constant auxiliary memory and produces each word in constant delay? Our results show that the answer depends on the set of edit operations that are allowed, and on the computational model that is used (e.g., which instructions are allowed, and what counts as memory). We study this problem first for a kind of Turing machines called tape machines, and then for another formalism that we introduce, called deque machines. In these two frameworks, we construct machines that enumerate with constant delay and while using constant auxiliary space. Note that this does not contradict the known lower bounds from the DAT model: we discuss this in more detail in Section 2 for tape machines, and for deque machines we are not aware of known lower bounds because deque machines can perform circular shifts in unit time. We present our contributions in more detail below.
Contributions.
We first present tape machines, which are a kind of deterministic Turing machines that also resemble linear bounded automata [18]. Tape machines have a finite set of states, some of which are distinguished as output states, along with a single working tape and one head. The tape alphabet is . The tape is initialized with the word and stays of length throughout. Like a Turing machine, a tape machine updates its tape based on its internal state and on the symbol under the head. It may then change the bit under the head, move its head left or right, and change its state. Note that the machine only has a single working tape, and no input or output tape. The word on the working tape is produced in unit time whenever an output state is reached.
This definition ensures that tape machines satisfy our constant-memory requirement: in addition to the working tape used to store the current word, the only auxiliary memory that they use is their internal state, from a constant-sized set of states which is independent from . Our goal is to design a Hamiltonian tape machine: for every word length , when started on the word , the machine must produce all the words of exactly once (i.e., each word is seen exactly once in an output state), and must then halt. Further, the machine must be constant-delay: there must be a constant independent from such that the machine produces a new word after at most steps.
It is not obvious at all from the definition that Hamiltonian constant-delay tape machines exist, because they have no working memory beyond the tape used to store the words to be produced. In particular, the constant-delay requirement implies that the bits flipped from one word to the next must be at constant distance from one another (i.e., if we flip bit and then bit then the distance must be small). This latter requirement is not satisfied by the BRGC, but it is obeyed by some Gray codes, for instance, the -skew-tolerant codes of [25] (attributed to [30]), where is the maximum distance between consecutively flipped bits. Our first contribution is to show that we can in fact design a Hamiltonian tape machine. What is more, we can strengthen the result and ensure that the machine is Hamming-1, i.e., the Hamming distance between any two successively produced words is 1: this property is satisfied by Gray codes such as the BRGC or the ones of [25]). Formally:
Theorem 1.1.
There exists a Hamiltonian constant-delay Hamming-1 tape machine.
The result is intuitively established by implementing a traversal of a complete binary tree with the “even-odd trick” [17, 28], and refining it to make it Hamming-1. It turns out that our machine implements a code closely related to [25, Construction A] (with ), despite having no apparent relationship to the simple inductive definition of [25]. Thus, we can also see Theorem 1.1 as a construction showing that (a variant of) the code of [25, Construction A] can be implemented to use only constant delay and constant auxiliary memory. We explain how the two codes relate in [1, Appendix B]. We also show that our machine can implement counters by detailing the decrement function, and discuss rank and unrank functions in [1, Appendix B]. We relate our implementation to works using the DAT model [16, 6, 22], and show that it is competitive with the best counter implementations in the RAM model [14].
Our second contribution is to study a computational model that we call the deque machine, in line with other works studying machines augmented with deques [4, 21]. In this model, the word is stored in a double-ended queue, the machine can read the first and last bits of the word, and it can perform push and pop operations on the left and right endpoints. The motivation for this model is to ensure that the entire configuration of the machine consists of the current word plus the finite state, in contrast with tape machines that arguably hide auxiliary memory bits in the position of the head. Moreover, deque machines are effective models to implement push-pop edits on words, as studied in [3] for enumeration of regular languages. Finally, allowing only endpoints modifications is natural in other contexts, such as enumerating walks in a graph, which is a core task in modern graph database query processing [12]. Indeed, the task of enumerating binary words studied in the present paper is a first step towards the efficient enumeration of walks in graphs: it corresponds to walk enumeration for the specific graph that has one vertex and two self-loops labeled 0 and 1.
It is known that we can indeed enumerate all binary words with constantly many endpoint modifications between each word, as follows from universal words [10] or Hamiltonian paths in so-called Shuffle Exchange networks [15]. So our second contribution is to design deque machines that can produce such codes while only using constant auxiliary memory:
Theorem 1.2.
There exists a Hamiltonian constant-delay deque machine.
The first step to show this result is to notice that the tape machine from Theorem 1.1 can be adapted into a constant delay deque machine that produces all binary words once but then continues to run indefinitely and produces duplicates. As it turns out, the main challenge is to detect when the enumeration is complete, for which we present two alternative techniques which we hope can be of independent interest.
Our third contribution is to show that the model of deque machine is “minimal” in the sense that further restricting the edit operations makes it impossible to design Hamiltonian machines. We first study queue machines, where insertion is only possible at the left endpoint. We remind that it is indeed possible to visit all words of via left-push and right-pop using the construction of universal words, but show that this cannot be achieved by a queue machine (i.e., with constant auxiliary memory), even without the constant-delay requirement. We next study stack machines, where we push and pop at one end only, and show that in a sense such machines also cannot satisfy the constant-memory requirement.
Paper outline.
In Section 2, we define our model of tape machines and construct one that proves Theorem 1.1. We do the same in Section 3 for deque machines and Theorem 1.2. Finally, in Section 4 we study weaker computation models (queue machines and stack machines) and show that Hamiltonian machines of this kind do not exist. We also provide implementations to run our tape and deque machines [2].
2 Tape Machines
This section presents tape machines, which store the current word on a tape. We first define tape machines formally. Then, we explain how to construct such machines that enumerate all binary words of length in constant delay. Last, we build a machine which is additionally Hamming-1, i.e., it only flips one bit between two consecutive words, proving Theorem 1.1.
Machine model.
A tape machine is intuitively a variant of linear bounded Turing machines [18] where we additionally distinguish some states as output states. Formally, let and be fresh symbols to be used as left and right markers. A (deterministic) tape machine consists of a set of states, an initial state , a halting state , a set of output states, and a transition function . The arguments to the function describe the current state and the tape symbol read; and the return value describes the next state, the tape symbol written, and the motion of the head. We require that when reads the beginning-of-word marker symbol then it writes back and moves to the right, and likewise for moving to the left; further, never writes the marker symbols otherwise. A configuration of is a triple consisting of a state, the contents of the tape, and the position of the head: for brevity we will write them as a pair indicating the state and the tape contents with the head position written using a red mark. We sometimes use a gray mark to indicate the position of the head in the previous configuration.
For a given word length , the machine starts its execution in the initial configuration . The run of from is then the deterministic and potentially infinite sequence of configurations defined as expected. The only difference with Turing machines is the presence of output states: each time visits an output state, it produces in unit time the word obtained from the current tape by discarding and . (Note that the head position has no impact on the produced word .)
We study tape machines satisfying some requirements. First, a tape machine is Hamiltonian if, for every length , the run of from terminates and produces each word of exactly once. Note that we can always assume that for arbitrary constants , because codes for length can be hardcoded as a subroutine of . Second, a tape machine is constant-delay if there is a constant (depending only on but not on the word length ) that bounds the time before the first output, the delay between two consecutive outputs, and the time between the last output and the end of the run.
Constructing Hamiltonian constant-delay machines.
It is easy to see that Hamiltonian tape machines exist if we forgo the constant-delay requirement. For instance, we can follow the usual construction of the BRGC: start from the word , flip the rightmost bit on odd steps, and flip the bit that is to the left of the rightmost on even steps. This can be implemented by a tape machine whose state stores the parity of the step number. In odd steps, the machine moves the head to the rightmost symbol and flips it. In even steps, the machine moves the head to the rightmost symbol, scans leftwards until it finds the symbol to flip, and flips it. However, this tape machine has a delay that is not constant, i.e., it is not independent from the word length . Our challenge in this section is to build a tape machine that obeys the constant-delay requirement: this is not obvious because it implies in particular that tape modifications must be entirely guided by the symbols at constant distance from the head and based on the current state (which has constant size). We next present a tape machine that meets these requirements.
Proposition 2.1.
The tape machine of Figure 1(b) is constant-delay and Hamiltonian.
This is a first step towards proving Theorem 1.1, which we present for pedagogical reasons: it will help understand the Hamming-1 construction presented later, and also introduces key ideas used throughout the paper. For the sake of clarity, here and in other proofs, we describe the operation of a tape machine by specifying transitions that read and write multiple symbols in one go: for some constant (independent from the word length), the machine reads and writes the symbols left and right of the head in a window of size centered on the head. This can be encoded in the formal model presented above up to increasing the state space and the delay by some function of : we can simply hardcode a constant-length sequence of transitions that reads all symbols around the head and then overwrites them. We will use in the proof below.
Proof of Proposition 2.1.
Let be the word length. When the run begins, we produce the word , and toggle the first bit to change the tape contents to . We then explain how we enumerate the remaining words, called non-zero words in what follows.
Let us construct a bijection between the non-zero words and the nodes of the complete ordered binary tree of depth ; we will then explain our enumeration in terms of the tree. By distinguishing the rightmost , each non-zero word can be written as for some binary word and some number of ’s. Hence the non-zero words are in bijection with the nodes of , that we illustrate in Figure 1(a) for (ignoring for now the blue numbers and red marks). The root of corresponds to the word . Now, for , if is the word corresponding to an internal node , then the 0-child of corresponds to the word and its 1-child corresponds to the word . In summary, the word , where and , encodes the node in that is reachable from the root by the path (reading from left to right; is shown in orange in Figure 1(a)).
We enumerate the nodes of in a way that ensures that consecutive nodes are at distance at most from each other. We do this via the “even-odd trick” [17, 28] (see also [29]): we do a depth-first traversal of and produce the nodes in prefix or postfix order, depending on the parity of the depth (the root being at even depth). Formally, starting with the root, we do the following on every node with children and :
-
if the depth of is even then we produce , then recurse into , then recurse into ;
-
if the depth is odd then we first recurse into , then recurse into , and then produce .
The order in which nodes are enumerated by this procedure for is shown in blue in Figure 1(a) (starting at index because we produced the word at the beginning).
The correctness of the machine hinges on the following claim, which is easily proved by induction using the transition table of given in Figure 1.
Claim 2.2.
For every word , , visits exactly two configurations of the form ): the first time , and the second time , where .
We now give a high level explanation of how performs the traversal on . It maintains its head on the rightmost , and memorizes with its state the parity of (the depth of the node corresponding to) the current word, and whether it is currently going up or down. Then, one may check that the following elementary tests/operations can be achieved by local reads/writes in a window of size centered on the head.
-
1.
Check whether the current tape encodes a leaf or not, by looking at the right symbol (which is always either or ).
-
2.
Check whether the current tape encodes the root (the symbol left of the head is ), a -child ( is ) or a -child ( is ).
-
3.
Go from one node to its -child: , i.e., set to 0 the bit under the head, move the head right (the old head is shown in gray), and set to 1 the bit under the head.
-
4.
Go from a -child to its sibling -child: , i.e., flip the bit left of the head.
-
5.
Go from a -child to its parent: .
Formally, the tape machine described in Figure 1(b) starts by outputting and reaching the configuration via the first transition in the table: its tape corresponds to the root of and the state is . Then, implements the above elementary tests/operations using the four middle transitions, in order to perform a full traversal of . This traversal ends when the configuration is reached again, this time with state , and then we take the last transition and end the run.
By analyzing the sequence of transitions between two words produced by , one can observe that the maximal distance between flipped bits is two. Further, the code changes at most 3 bits from one word produced to the next (between the 9th word and the 10th for instance). Because , this code is technically not a Gray code but what some authors call a quasi-Gray code [6]. We now show how to fix this and build a Hamming-1 machine.
Hamming-1 machines.
A tape machine is Hamming-1 if, for any , for any two consecutive words and that are produced in the run of on , then the Hamming distance between and is (i.e., there is a single bit that changes).
Whenever a Gray code is implemented by a constant-delay tape machine, then the maximal distance between flipped bits is bounded by some constant , a property called -skew-tolerance [25]. Most Gray codes, such as the BRGC, are not skew-tolerant, and the existence of 1-skew-tolerant Gray code is an open question [20]. However, [25] give examples of -skew-tolerant Gray codes for and ; the code for , called construction A, is of particular interest to us. Indeed, we now show how to construct a machine that is Hamming-1, Hamiltonian and constant-delay, which turns out to implement a Gray code that is closely related to construction A; see [1, Appendix B] for details.
Proposition 2.3.
The tape machine , defined in Figure 2(a), is constant-delay, Hamiltonian and Hamming-1.
Proof.
Let be the word length. We ignore for now the two words and that are enumerated first and last, respectively. All other words are of the form for and , by distinguishing the rightmost and the bit that precedes it. As it was the case for , the machine maintains its head on the rightmost , as can be seen by inspecting its transition table (Figure 2(a)). We use the notation and .
Consider the complete ordered binary tree of depth . To every node of depth , we associate two words of length : the bottom word and the top word . They have the form and where , and where are defined as follows: is the path from the root to and is the parity of the number of ’s in . For instance, the bottom word associated with the root is (i.e., is the empty word and ); and among , that are associated with the same node , is the bottom word (i.e., and ).
Let be any internal node having bottom word and top word . We let denote the -child of and its -child. This implies that we have , we have , and we always have and .
Then, it may be observed that the following word pairs are at Hamming distance :
-
1.
and , that is the bottom word of and the bottom word of its parent;
-
2.
and ; that is the top word of and the bottom word of its sibling;
-
3.
and , that is the top word of and the top word of its parent;
-
4.
and , for every leaf (remark that this is true for every node more generally).
These claims are the basis of a traversal of , inductively defined as follows. Starting from the root, and letting be the current node, we first produce the word , then recurse into the -child of , then recurse into the -child of , then produce the word . Using a simple induction (item 4 for the base case and 1-3 for the induction; see also Figure 2(b)), one can show that this traversal induces a Gray code, when the missing words and are produced first and last, as we do.
The tape machine then produces exactly this code, as follows from:
Claim 0.
For every node of with bottom word , if we start the machine on configuration then it will produce the words of the above traversal on the subtree rooted at , and it will reach configuration .
It is routine to prove this claim by induction on (see Figure 2(b)), inspecting the transitions of . All that remains is to check the behavior on the root of :
-
When starts, it first produces the word and then it reaches the configuration , that is with tape with its head on the rightmost .
-
From the configuration , that is with tape with its head on the rightmost , the machine produces and then halts.
Connections to the DAT model.
Our results relate to known algorithms and lower bounds on the efficient implementation of quasi-Gray codes in the Decision Assignment Tree (DAT) model or bit-probe model [16, 6, 7, 22, 23]. In this model, the read and write operations performed on the memory are specified following a decision tree. However, the DAT model is a black-box model which does not restrict the computation that the machine performs, or the position in the word of the bits that are read and written. By contrast, in our model of tape machines, the next reads and writes must be decided by following a fixed transition table (independent from the current word length), and they must happen close to where the head is located. For this reason, the known algorithms for (quasi-)Gray codes in the DAT model do not imply the existence of tape machines that satisfy our requirements. Conversely, translating tape machines to the DAT model does not improve on the state of the art in that setting, because our tape machines implicitly store the position of their head: in the DAT model this amounts to extra bits that can be arbitrarily read and written at each step. These extra bits are why tape machines do not contradict the known lower bound on the number of bits read at each step in the DAT model (shown in Fredman [16] for Gray codes and claimed by Raskin [23] for quasi-Gray codes).
Decrements and connection to counters in the RAM model.
Our results also relate to a line of work that has studied the efficient implementation of counters in the RAM model, where algorithms are run on a machine featuring memory words of logarithmic size. In this model, [14] presents a counter that can perform increments and decrements in time and using additional memory words; this answered an open problem stated by Demaine [11]. The tape machines that we presented can easily be implemented as a RAM algorithm, where we store the current word in a table of bits and keep one auxiliary word of bits for the head position and a constant number of extra bits for the state. The increment operations are specified by the machines and and they can be performed in constant time. Further, ’s and ’s transition tables can be checked to be injective, so that we can also perform decrements in constant time simply by reversing the transitions. Hence, our constructions provide an alternative solution to Demaine’s problem, using a single auxiliary -bit word (instead of two in [14]), and additionally ensuring that the successive counter values form a Gray code. Another advantage is that our counter support integers of any size, since we can go from size bits to in constant time with the same machine. Hence, we could use it to replace an ad-hoc technical construction in [8, Section 6] used to detect large values of increasing size with constant overhead. We further discuss in [1, Appendix B] how to implement the rank and unrank operations.
3 Deque Machines
In the previous section, we have implemented Gray codes with a constant-delay tape machine. These machines only have constantly many states, but they arguably use more than constant memory: their configuration also stores the position of the head, which would require a logarithmic number of additional bits. In this section, we investigate how to produce Gray codes in a different computation model called deque machines, where the additional memory used is really constant. Intuitively, the current word is stored on a deque, i.e., a doubly-linked list allowing us to perform accesses, insertions, and deletions at the two endpoints of the word. In this model we are not concerned with how the doubly-linked list would be implemented on hardware, and we simply assume that these endpoint operations take unit time. The machine has a constant-sized internal state, but it does not feature a head: it can only access the symbols that are at the endpoints of the deque.
Like in the previous section, our goal is to construct a deque machine which is Hamiltonian and constant-delay. A necessary condition for the existence of such machines is the existence of so-called push-pop quasi-Gray codes, i.e., codes that visit each word of exactly once by producing each word from the previous one via push and pop operations. Such codes are indeed known to exist, e.g., from universal words [10] or from Hamiltonian paths in the Shuffle Exchange network [15]: see [1, Appendix C] for details. Hence, we will investigate in this section whether push-pop quasi-Gray codes can be implemented by machines with constant auxiliary memory, with the goal of proving Theorem 1.2 from the introduction.
The section is structured as follows. We first formally define deque machines. Then, we build a first deque machine which is constant-delay but only prefix-Hamiltonian: it produces all words but then loops forever instead of halting. We then investigate how can be improved to be Hamiltonian, i.e., to correctly halt when enumeration has finished. We discuss in [1, Appendix C] how to implement a counter with deque machines by supporting the decrement operation.
Machine model.
A deque machine consists of a set of states, an initial state , a halting state , a set of output states, and a transition function . The arguments to the transition function describe the current state and the symbols at the left and right endpoints of the word, and the return values describe the new state, the endpoint at which the machine pops a symbol, the endpoint at which the machine pushes a symbol, and which symbol it pushes. (If both endpoints are the same, then the machine simply overwrites the symbol at that endpoint.) Thus, a configuration of such a machine consists simply of a state and of a non-empty word. The semantics of deque machines is again defined as expected. Like in Section 2, for a word length , we start the machine with the word in state and the machine produces the current word in unit time whenever it visits an output state. We will investigate machines that are Hamiltonian and constant-delay in the same sense as in Section 2.
One first idea to design deque machines would be to translate tape machines in a black-box fashion by taking the conjugate of the tape at the position of the head. Unfortunately, this naive approach does not work as-is [1, Appendix C]. Thus, the constructions presented in this section require new ideas on top of techniques from the previous section.
Constructing prefix-Hamiltonian machines.
We will start by designing a deque machine which is almost Hamiltonian but fails to halt. Formally, a deque machine is prefix-Hamiltonian if it satisfies the following: for every length , the first words that it produces are all the words of (without duplicates). After this, the machine can continue to run indefinitely, and in particular it is allowed to produce words that it has already produced. A Hamiltonian machine is of course prefix-Hamiltonian, but not vice-versa. The constant-delay requirement is unchanged: in particular it is imposed on the entire run. We now show:
Proposition 3.1.
The deque machine , defined in Figure 3(b), is constant-delay and prefix-Hamiltonian.
Proof sketch.
Just like the tape machine (Figure 1(b)) from Section 2, the deque machine is based on the depth-first traversal of a complete binary tree. Once again is treated independently and a word with one or more 1’s encodes a node in the complete binary tree of depth . However, the encoding is slightly different111In the tape machine , recall that the tape encodes the node reached by reading from the root (from left to right), and that we modify only on the right. On the other hand, a deque machine can only modify the endpoints of its deque. Hence the same node needs to be encoded either with or , where is the mirror of . We chose the former encoding in order for the path from the root to the node to be consistently read from left to right.: the tape machine from the previous section distinguished the rightmost 1 and the node reachable from the root by a path labeled was encoded by , but the deque machine will instead distinguish the leftmost 1 and encode that node by . The proof hinges on the analogue of ˜2.2 for :
Claim 3.2.
During the enumeration of the first words, visits each deque of the form exactly twice, first in state , then later in state , where .
See Figure 3(a) for the full binary tree in the case and [1, Appendix C] for more details.
The machine is not Hamiltonian because it does not halt at the correct time, due to the lack of left and right markers (, ). Indeed, should halt when it visits the root the second time (i.e., in the configuration ). We did not find how to detect that the current deque is : e.g., cannot store the number of ’s in the current word, or the current number of leading ’s, because these numbers depend on so they are not constant. This motivates the more complex techniques presented in the rest of this section.
To present them, we will need to understand the behavior of when it reaches the root for the second time, that is, in state . This corresponds to the step where the machine has produced every word and “should” halt.
Observation 3.3 (Parity is swapped at the root).
When the run of visits the root (i.e., the word ) at the end of the traversal, it is with state . Then, the run continues as follows. (Transitions and , below, are the ones labeled in Figure 3(b).)
At this point, the machine performs a second depth-first traversal of the tree. Recall that the first traversal starts in configuration while we can see above that the second starts in . This means the parity will be swapped for the full duration of the second traversal: during the second traversal, a claim similar to ˜3.2 holds with states and . When the second depth-first traversal ends, that is when reaches the root for the fourth time, it is with state . Then, the parity is swapped again by and restarts, looping indefinitely.
Constructing constant-delay Hamiltonian deque machines.
In the following, we improve (Figure 3(b)) in order to make it Hamiltonian, i.e., to detect when the enumeration can halt. This hinges on the fact that, unlike the root, some nodes of the complete binary tree of depth can be detected. Let be the first leaf of the 0-subtree of the root (corresponding to the word ), and the first leaf of the 1-subtree (corresponding to the word ). The nodes and are double-circled in Figure 3(a). Then:
Observation 3.4 ( and can be detected).
During the run of , the first time that is visited is the first time in the run that appears to the left of the current word, and the first time is visited is the first time in the run that appears to the left.
Note that, within the constant-delay bound of our deque machines, at each step we can pop the two leftmost characters and push them back; so indeed our machines can detect whenever the words or appear for the first time at the left endpoint. Our future deque machines will leverage ˜3.4 as follows. The traversal starts at (i.e., the word ) instead of the root . Then, they count the number of half-traversals since the start. One half-traversal spans either from (i.e., ) to (i.e., ), or conversely. The former visits the 0-subtree, minus the descent in the branch , plus the descent in the branch . The latter visits the remainder of the 1-subtree, plus the descent in the branch . Unfortunately, we cannot simply build a machine that performs two half-traversals, because by ˜3.3 the parity is swapped when the root is visited, so that the incorrect parity during the descent in the branch would lead to duplicates. We will now show two alternative ways to use the above and modify to a Hamiltonian machine: the double-traversal technique, and the lookahead technique.
Double-traversal technique.
We first build a Hamiltonian machine from with the double-traversal technique. The machine will perform four half-traversals (i.e., two traversals) starting from , and then it will halt. Each of these two traversals has an opposite parity by ˜3.3. We build the machine to ensure that the two traversals partition the output (using the parity), even though the machine is not aware of the moment when the parity is swapped.
Proposition 3.5.
The deque machine of Figure 4 is constant-delay and Hamiltonian.
We sketch the proof of Proposition 3.5 in the rest of this paragraph, before turning to the alternative lookahead technique. Let be the word length. We ignore the two words and , that are handled in a special way (see ˜3.7). The machine traverses the complete binary tree of depth (in contrast with , which used ; we will explain this later). Like , the machine stores whether it is currently going up or down the tree, along with a parity bit in the second component of its internal state. However, unlike , the machine starts at (the first leaf of the 0-subtree of the root, corresponding to the word ). For this reason, the parity bit maintains the parity of the height instead of the depth: the correct parity of a node encoded by is . (In particular, the correct parity of is , represented as in the state of the machine.)
Moreover maintains in its internal state the index of the current half-traversal (): the machine stops after reaching in the 4th half-traversal. The four half-traversals are regrouped into a first full traversal and a second full traversal, each going from back to . Let us further split each full traversal in two parts called A and B:
-
Part A is the majority of the traversal: starting at , traversing the tree until the root () is reached.
-
Part B corresponds to the last descent from the root () down to again, hence passing through all nodes of the form .
Parts A and B are not aligned with half-traversals, though part B is always included in the second half of each traversal (i.e., the visit of happens in part A). Let us stress that while maintains the current half-traversal, it does not know whether it is in part A or part B of the current full traversal. Furthermore, due to ˜3.3, the parity bit is equal to the correct parity during part A of the first traversal and it is swapped during part B of the first traversal. On the other hand, the parity bit is swapped during part A of the second traversal and correct again during part B of the second traversal.
Altogether, each node is visited once in each of the four possible combinations of . In order to produce each word only once, writes the current parity bit as the rightmost symbol of the current deque (with the convention and ). This special treatment of the rightmost symbol of the deque is why performs traversals of the binary tree instead of . (We note that, even though the parity bit is always written as the rightmost symbol of the deque, we still need to additionally keep track of parity in the internal state of , because the parity is part of the definition of which states are output states.)
The proof of Proposition 3.5 consists in showing that has the invariants stated by Claims 3.6 and 3.7, given below. They are established by a simple inspection of the transition table (Figure 4).
Claim 3.6.
Let be a word of length , for some . Let be the correct parity, and define and . The deques and are both visited twice by the run of , in the states and order given below.
-
If (i.e., is the root): is visited by states and ; while is visited by states and .
-
Otherwise, if (i.e., is in the first branch of the 0-subtree)): is visited by states and ; while is visited by states and .
-
Otherwise, if (i.e., is in the first branch of the 1-subtree): is visited by states and ; while is visited by states and .
-
Otherwise: is visited by states and ; while is visited by and ; where if the first bit of is , or otherwise.
Claim 3.7.
(Beware that the below is a parity bit.)
-
The deque is visited by state if is even, or by state otherwise. In particular, is produced once during the traversal.
-
The deque is visited by state and then by state if is even, or then by otherwise. In particular, is produced once during the traversal.
Lookahead technique.
An alternative way to make Hamiltonian is to use the lookahead technique. We think it is more flexible though more technical than double traversal.
The deque machine , defined in Figure 5, implements this technique. More precisely, performs two half-traversals (i.e., one full traversal) of , starting from . However, each time the machine visits a -child and moves to the state , it performs a “lookahead”: it descends to the leftmost leaf of and then ascends back to , before continuing the traversal (and descending again to the leftmost leaf of ). This first upward return to is possible because can detect the first node that is a -child while moving upward in the tree.
This lookahead phase requires keeping track of the height of the current node modulo , since in each node is visited four times instead of twice as in . Concretely, a node of height is output on its visit. Like , the machine detects the second visit of . This event occurs during the lookahead initiated from the root . Hence, is able to detect that it is visiting the root after this lookahead phase. The machine is thus able to adjust the stored height modulo before performing the final descent in . This allows to fix the issue from ˜3.3 and to produce the missing solutions in this branch.
Proposition 3.8 (Lookahead).
The deque machine , defined in Figure 5, is constant-delay and Hamiltonian.
We sketch the proof of Proposition 3.8 in the remainder of the paragraph. Let be a word length. Once again, we ignore for now the word which is handled in a special way, and focus on the other non-zero words. The top part of table Figure 5 describes a simplified version of the machine, that the reader should consider first. The actual machine is obtained by replacing the transition marked with by the three transitions given at the bottom of Figure 5. We will explain this at the end of the proof, together with the purpose of the state special.
The deque machine traverses the complete binary tree of depth . We use the same bijection between nodes of and nonzero words of length . The state of contains three components:
-
The first component of the state of stores whether it is currently going up or down the tree with four different values . The intuition is that correspond to the value of , whereas corresponds to the value of .
-
The second component of the state of stores the height modulo 4 of the current node (possibly with an offset after visiting the root, as we will explain).
-
The third component of the state is in , which indicates the half-traversal that we are currently doing, as we explain below.
More precisely, for the third component, we want to use ˜3.4 to detect the end of the enumeration. The initial value used for the third component is , which corresponds to the first half-traversal, i.e., the traversal of between (the first leaf of the 0-subtree of the root, corresponding to the word ) and (the first leaf of the 1-subtree of the root, corresponding to the word ). When traverses the leaf , it detects it by ˜3.4, and then transition () of Figure 5 is used to change the state to , indicating that the second half-traversal has started. Finally, when is traversed a second time by , we detect it again by ˜3.4, and then transition () is used, which changes the state to last. The machine then enumerates some missing words of the form (as we will explain at the end), and then halts.
We now explain the traversal in more detail. The machine starts at and mimic the traversal of by . The only difference is that it does a “lookahead” when it starts to go down the tree from a node which is a -child. More precisely, letting be the leftmost leaf of the subtree rooted in , the machine traverses the path three times: first going down (state ), then up (state ) and finally down (state ). When the leaf is reached in state , transitions to state , which corresponds to the state in . To slightly simplify the machine, we maintain the opposite of the height (modulo 4), that is: when the machine goes up the height is decremented, and it is incremented when the machine goes down.
The correctness of rely on Claims 3.9 and 3.10, which describe the configurations of when the tape contains at least two 0’s, and exactly one 0, respectively. Both are proved with straightforward inductions based on Table (Figure 5). The case of the tape is treated separately.
Claim 3.9.
Let be a word which is a non-zero word and not of the form (i.e., encodes a node that is not on the branch from the root to ). Let be the opposite of the height of in modulo 4. Then, four configurations of the form are reached by , successively in states , , , and , where is either ( is in between and in the traversal order) or ( is in between and the root). In particular each such word is visited in exactly one of the output states , depending on its height.
The previous claim guarantees that the words are produced once, except for the words of the form : these are the words of the leftmost path, i.e., the path from the root (corresponding to the word ) to the leftmost leaf (corresponding to the word ). We deal with the elements of this branch differently, since we know that their height is shifted by one when going over the root, by ˜3.3 (generalized to the present setting, where we keep track of the opposite of the height, and we do it modulo 4 instead of modulo 2). These words are first traversed when going up from a -child, that is in state , before the traversal has reached the root for the first time – hence with the correct height. Then, thanks to the lookahead, first traverses the leftmost branch up and down in states and , with a height shifted by one. When again at the root of the tree, it has transitioned to the state last thanks to the lookahead, with transition (): this uses the analogue of ˜3.4 to argue that the machine detects that it has now revisited after having visited . Hence, before does the last descent along the leftmost path in state , the height is again decremented by one to avoid duplicates, in transition . Hence, all the words of the leftmost path are enumerated exactly once, as precisely stated in the following claim.
Claim 3.10.
Let be a word for some , and let . Then, reaches a configuration of the form four times by , successively in states , , , and , for some value of (namely when is the root and otherwise).
Moreover, the word is produced exactly once, depending on the value.
Finally, we must explain how to deal with the word , which is the purpose of the state called “special” and of the three transitions at the bottom of Figure 5 to replace transition . Observe that the machine visits the word only once in state , see ˜3.3. Hence, this word is produced by if and only if . The complete version of the transition table of Figure 5 ensures the following: when it visits the root in state before the last descent, it first produces if . These are the transitions given at the bottom of Figure 5 to replace the transition : we distinguish two cases depending on whether (where we do the analogue of ) or not (where we additionally output via the special state).
We last argue why the machine satisfies the constant-delay requirement. For this, we observe that the second component of the state always stores the opposite of the current height modulo 4 plus some offset , and the offset changes at only constantly many points in the enumeration (namely, the first time we visit the root where it is decremented, and the second time when it is fixed when revisiting the root after the lookahead). So it suffices to show the constant-delay guarantee whenever the offset does not change. We can also ignore the additional states mentioned at the end of the previous paragraph, as they are only visited once.
When the offset does not change, the machine simply performs a traversal of the complete binary tree , except that descents from a -child are replaced by a back-and-forth successively involving the states . If we stay in the same state for more than 3 steps, then we visit all values of the second component, and one of the states encountered must be an output state. So a long run without outputs must change states among every 3 steps at most. Looking at the possible transitions between states, these state transitions must include a transition from to , or from to . But these transitions only happen at leaves of , and since we assumed that we do not stay in the same state for more than 3 steps it easy to see that the time between the 4 visits of the leaf that are prescribed by ˜3.9 must happen within a constant time bound.
4 Lower Bounds: Queue Machines and Stack Machines
We now study variants of deque machines where we restrict which operations are allowed on the endpoints. We consider queue machines and stack machines, and show that no such machine can be Hamiltonian.
Queue machines.
We define queue machines as a variant of deque machines that can only push to the left and pop to the right; but we still augment them with the ability to read the rightmost symbols of the word, for some constant . For convenience, we assume without loss of generality that the current word is no smaller than . A queue machine is then defined similarly to a deque machine, with the transition function having signature . The arguments to the transition function describe the current state and the rightmost bits of the word. The return values describe the new state and the word with length pushed to the left of the deque, with the rightmost characters being popped so that the word length stays the same. Note that the definition of queue machines does not allow them to read the leftmost bits of the deque, but they can be modified to do so without loss of generality, e.g., by remembering the most recently pushed bits as part of their internal state.
We investigate queue machines that are Hamiltonian and constant-delay in the same sense as in Section 2, and we show no such machines exist, even without bounding the delay:
Theorem 4.1.
There exists no Hamiltonian queue machine.
The proof is by contradiction and uses a pumping-like argument: we start from the last state visited by the machine, we argue that this state cannot occur on any other word, and then successively eliminate more and more states by building longer and longer words. Note that the result applies even without requiring machines to be constant-delay, but that it would not apply if we could have unlimited auxiliary memory: indeed it is known that we can produce all binary words with left-push and right-pop operations.
Proof of Theorem 4.1.
For the sake of contradiction, assume there is a Hamiltonian queue machine with set of states , which reads bits at a time. Let be some integer: we consider the word of size , such that is the last configuration of before reaching the halting state. Let us consider the words and : they are both enumerated by when generating the words of size , in states and respectively. Remark that and cannot both be equal to , because whenever is in configuration for some then it will reach the halting state (as the transition only depends on the last bits and on the current state ). W.l.o.g., we assume that we have . Hence, let and . We consider the run of from up to the moment when the halting state is reached, and we let be the word formed of all words pushed to the left of during this run of until halts. For instance, if pushes , then , then and then halts, then . Note that can be exponentially longer than .
Notice now that the run of on , for any , will use exactly the same transitions (in the same order) as the run on , and then it halts. Indeed, an easy induction shows that the leftmost bits will always be equal in both cases. In particular, all these runs have the same length (measured as the number of transitions performed). Let us now consider the four words for , and the run of for words of length . For the same reason as before, at most one of these four words can be visited in state during that run. Moreover, only one of these four words can be visited in state during that run. Indeed, only one configuration can be at position from the end. Thus, pick a word with which is visited in a state during the run of from its initial configuration. We then let be the concatenation of all words pushed to the left of by on the run from until halts.
This method easily generalizes to build sequences of words and of states that satisfies: for every , there is at most one word of length such that the run of from its initial configuration reaches . When equals the number of states in , we reach a contradiction.
Note that the proof above also rules out the existence of Hamiltonian queue machines in somewhat more powerful models, e.g., if the machine is also allowed to edit in-place the leftmost and rightmost characters for some constant without changing the length.
Stack machines.
We now move from queue machines to stack machines. Stack machines are defined like queue machines, except that they can only push and pop on the right endpoint.
Formally, a stack machine is a tuple with and respectively the initial state and halting state, with the output states, and , where signals that the stack is empty. The semantics are defined as expected: based on the current state and the rightmost bit of the current word (or the marker), the machine transitions to some state and either pops the rightmost bit or pushes a bit to the right of the word. (Popping on the empty word has no effect.)
With this definition, stack machines obviously cannot achieve constant-delay enumeration of for arbitrary . Indeed, for any delay bound , the machine will not have time to change the bits at distance greater than from the right endpoint, which is problematic as soon as . However, one can ask whether Hamiltonian stack machines can exist without the constant-delay requirement. The answer is negative.
Proposition 4.2.
Let be a stack machine and be its number of states. Then there are words of length that the machine never visits.
To prove Proposition 4.2, we first prove a general lemma reminiscent of pumping lemmas:
Lemma 4.3.
Let be a stack machine with state space , and let . Assume that the machine visits a word of length at time and later visits a word of length at time , with all words between and having length . Then the machine never halts and all words visited after have as a prefix.
Intuitively, we show that we must reach on one word on a state and reach a larger word on the same state without having popped any bit from . Once this has happened the sequence repeats indefinitely. The formal proof is below:
Proof of Lemma 4.3.
Fix a word of length visited at a time and a word of length visited at a time , with all words between and having length . Define a sequence of timestamps and corresponding visited words in the following way: and , then is the moment where we visit a word which is the last word of length visited between and , and is the last moment where we visit a word which is the last word of length visited between and , and so on. At the end, the time is such that and is a word of length which is the last word of length visited between and , so it must be the case that and . Further note that the definition ensures that the are successive prefixes of one another: each with is a prefix of length of
By the pigeonhole principle, there are two indices such that the state reached by the machine at time and (reaching words and respectively) is the same state . Recall that we have and with .
Now, consider the execution of the machine from time onwards. At , the machine was in the same state, and it followed a sequence of transitions that never popped below depth until reaching : indeed is the last visit of a word of length between and so if the machine popped below between and then it would visit a word of length again before and this would contradict the definition of . Then, from , the machine will replay the same sequence of transitions, in particular not popping below , until we reach after time the state and the word . We can repeat this argument indefinitely to show that the machine never halts and all words produced from that point onwards start with , hence with .
We can now prove Proposition 4.2:
Proof of Proposition 4.2.
We reason by contradiction. Let be a stack machine, let be the number of states of , let as in the statement, and assume by way of contradiction that visits all words of length .
Consider the first word of length that visits whose first two bits are different from , and consider the moment where last visited the word before visiting (this must have happened because the initial tape starts with so must have changed them and visited ). From Lemma 4.3 we know that all words visited afterwards start with . But, letting be a sequence of two bits such that and , we know that no word of length starting with was visited, so cannot visit all words of length .
This result also implies that prefix-Hamiltonian stack machines do not exist, or even stack machines that visit all words of length for sufficiently large (in particular they cannot output all such words, even with duplicates). This also rules out the existence of stack machines to enumerate other languages than , for instance (the binary words of length up to ), or the infinite language .
However, with unlimited memory, some languages can be enumerated in constant delay by performing push-right and pop-right operations. Since we cannot enumerate in constant-delay, we focus on other languages.
We first note that enumeration can easily be done in constant-delay for the language in constant delay with push-right and pop-right operations. This contrasts with the inexistence of stack machines for this language (as follows from Proposition 4.2).
Claim 4.4.
For any we can design a (length-dependent) push-pop-right Gray code that produces all words over of length up to with a constant number of push-right and pop-right operations between any two produced words.
Proof.
This is simply by exploring the complete binary tree of depth and using again the even-odd trick.
We last point out that the above is not possible if we want to produce the infinite sequence of the words of (i.e., of arbitrary length). This is intuitively because we must eventually produce all short words and then we can no longer change the first bits of the word. This is made formal in [3, Theorem 6.2].
5 Conclusion and Future Work
We have studied how to enumerate all binary words of length in constant delay and constant auxiliary space. We defined two tape machines to perform that task ( and ), one of which also implements a Gray code (). We also constructed two deque machines that meet our goal ( and ), all built by improving a simpler deque machine () to make it halt at the end of the enumeration. Our work opens two main lines of interesting questions.
First, can our constructions be improved? For tape machines, we have shown that surprisingly implements a code similar to the 3-skew-tolerant Gray code of [25]. The same paper presents a 2-skew-tolerant code, and it is not clear if it can be implemented by a tape machine. For deque machines, there are at least two ways to improve and : supporting decrements, which seems to boil down to detecting that the enumeration is back at the start; and minimizing the distance between consecutive outputs, for a relevant notion of distance that generalizes Hamming-1 by taking into account cyclic shifts. Another direction for improvement is to look at even weaker models: we already know that restricting the operations allowed on deque machines makes them too weak for our purposes, even with unrestricted delay. Can we somehow weaken tape machines and still meet our goal?
Second, can our constructions be generalized? Indeed, while we have focused on enumerating all binary words of length , our constructions would easily extend to enumerating binary words of length in increasing order of length. However, it is not clear that our work generalizes to harder cases, such as enumerating all -ary words (which may lead to different bounds [9]), or all words of an arbitrary regular language. More generally, it would be especially interesting to study how we can use our techniques to enumerate all walks of a directed graph with constant delay and constant additional memory, with possible applications to graph database query processing. We could approach these tasks by devising variants of our constructions relying on efficiently encoding depth-first traversals of trees, but unfortunately the techniques used to build from and from (e.g., lookahead, double traversal, storing state on the tape/deque) all rely on specific properties of , which are not simple to extend already in the case of larger alphabets. The enumeration of regular languages with constant delay has also been studied in [3], featuring push-pop edits (reminiscent of deque machines) and push-pop-right edits (reminiscent of stack machines). Their characterization of enumerable languages is given in a non-uniform model, but it implies a necessary condition for languages to be enumerable in our models. A natural question is then to understand if the algorithms of [3] can be implemented with constant additional memory, and if possible with a machine size that is not much larger than an automaton for .
References
- [1] Antoine Amarilli, Claire David, Nadime Francis, Victor Marsault, Mikaël Monet, and Yann Strozecki. Gray codes with constant delay and constant auxiliary space, 2026. Preprint. doi:10.48550/arXiv.2602.11791.
- [2] Antoine Amarilli, Claire David, Nadime Francis, Victor Marsault, Mikaël Monet, and Yann Strozecki. Tape and deque machines implementing gray codes (version 1.0). Gitlab repository. URL: https://gitlab.com/marsault/constant-delay-gray-code-public/.
- [3] Antoine Amarilli and Mikaël Monet. Enumerating regular languages with bounded delay. In STACS, 2023. doi:10.4230/LIPIcs.STACS.2023.8.
- [4] Kathleen Ayers. Deque automata and a subfamily of context-sensitive languages which contains all semilinear bounded languages. Theoretical Computer Science, 40, 1985. doi:10.1016/0304-3975(85)90164-1.
- [5] James R. Bitner, Gideon Ehrlich, and Edward M. Reingold. Efficient generation of the binary reflected Gray code and its applications. Communications of the ACM, 19(9), 1976. doi:10.1145/360336.360343.
- [6] Prosenjit Bose, Paz Carmi, Dana Jansens, Anil Maheshwari, Pat Morin, and Michiel Smid. Improved methods for generating quasi-Gray codes. In SWAT, 2010. doi:10.1007/978-3-642-13731-0_22.
- [7] Gerth Stølting Brodal, Mark Greve, Vineet Pandey, and Srinivasa Rao Satti. Integer representations towards efficient counting in the bit probe model. Journal of Discrete Algorithms, 26, 2014. doi:10.1016/j.jda.2013.11.001.
- [8] Florent Capelli and Yann Strozecki. Geometric amortization of enumeration algorithms. In STACS, 2023. doi:10.4230/LIPIcs.STACS.2023.18.
- [9] Diptarka Chakraborty, Debarati Das, Michal Kouckỳ, and Nitin Saurabh. Space-optimal quasi-Gray codes with logarithmic read complexity. In ESA, 2018. doi:10.4230/LIPIcs.ESA.2018.12.
- [10] Fan Chung, Persi Diaconis, and Ron Graham. Universal cycles for combinatorial structures. Discrete Mathematics, 110(1-3), 1992. doi:10.1016/0012-365X(92)90699-G.
- [11] Erik Demaine. Advanced data structures: Lecture 17, 2012. URL: https://courses.csail.mit.edu/6.851/spring12/lectures/L17.html.
- [12] Alin Deutsch, Nadime Francis, Alastair Green, Keith Hare, Bei Li, Leonid Libkin, Tobias Lindaaker, Victor Marsault, Wim Martens, Jan Michels, Filip Murlak, Stefan Plantikow, Petra Selmer, Hannes Voigt, Oskar van Rest, Domagoj Vrgoč, Mingxi Wu, and Fred Zemke. Graph pattern matching in GQL and SQL/PGQ. In SIGMOD. ACM, 2022. doi:10.1145/3514221.3526057.
- [13] Gideon Ehrlich. Loopless algorithms for generating permutations, combinations, and other combinatorial configurations. Journal of the ACM, 20(3), 1973. doi:10.1145/321765.321781.
- [14] Amr Elmasry and Jyrki Katajainen. In-place binary counters. In MFCS. Springer, 2013. doi:10.1007/978-3-642-40313-2_32.
- [15] Rainer Feldmann and Peter Mysliwietz. The Shuffle Exchange network has a Hamiltonian path. Mathematical systems theory, 29(5), 1996. doi:10.1007/BF01184811.
- [16] Michael L. Fredman. Observations on the complexity of generating quasi-Gray codes. SIAM Journal on Computing, 7(2), 1978. doi:10.1137/0207012.
- [17] Jerome J. Karaganis. On the cube of a graph. Canadian Mathematical Bulletin, 11(2), 1968. doi:10.4153/CMB-1968-037-0.
- [18] S.-Y. Kuroda. Classes of languages and linear-bounded automata. Information and control, 7(2), 1964. doi:10.1016/S0019-9958(64)90120-2.
- [19] Zsuzsanna Lipták, Francesco Masillo, Gonzalo Navarro, and Aaron Williams. Constant time and space updates for the sigma-tau problem. In SPIRE, pages 323–330, 2023. doi:10.1007/978-3-031-43980-3_26.
- [20] Torsten Mütze. Combinatorial gray codes — an updated survey. The Electronic Journal of Combinatorics, Dynamic Surveys, 2023. doi:10.37236/11023.
- [21] Holger Petersen. Stacks versus deques. In Proceedings of the 7th Annual International Conference on Computing and Combinatorics, COCOON ’01, page 218–227, 2001. URL: https://dl.acm.org/doi/10.5555/646719.702245.
- [22] M. Ziaur Rahman and J. Ian Munro. Integer representation and counting in the bit probe model. Algorithmica, 56(1), 2010. doi:10.1007/s00453-008-9247-2.
- [23] Mikhail A. Raskin. A linear lower bound for incrementing a space-optimal integer representation in the bit-probe model. In ICALP, volume 80 of LIPIcs, 2017. doi:10.4230/LIPIcs.ICALP.2017.88.
- [24] Frank Ruskey. Combinatorial generation. Working Version (1j-CSC 425/520), 2003. URL: https://page.math.tu-berlin.de/˜felsner/SemWS17-18/Ruskey-Comb-Gen.pdf.
- [25] Gabriel Sac Himelfarb and Moshe Schwartz. Improved constructions of skew-tolerant Gray codes. IEEE Transactions on Information Theory, 71(10), 2025. doi:10.1109/TIT.2025.3592490.
- [26] Carla Savage. A survey of combinatorial Gray codes. SIAM Review, 39(4), 1997. doi:10.1137/S0036144595295272.
- [27] Joe Sawada and Aaron Williams. Solving the sigma-tau problem. ACM Transactions on Algorithms (TALG), 16(1), 2019. doi:10.1145/3359589.
- [28] Milan Sekanina. On an ordering of the set of vertices of a connected graph. Publ. Fac. Sci. Univ. Brno, 412, 1960.
- [29] Takeaki Uno. Two general methods to reduce delay and change of enumeration algorithms. National Institute of Informatics (in Japan) Technical Report E, 4, 2003. URL: https://www.nii.ac.jp/TechReports/public_html/03-004E.pdf.
- [30] Elizabeth L. Wilmer and Michael D. Ernst. Graphs induced by Gray codes. Discrete Mathematics, 257(2), 2002. doi:10.1016/S0012-365X(02)00516-2.
