Skip to main content
Add explanation, example tree.
Source Link
Eman Yalpsid
  • 1.6k
  • 11
  • 16

On a possible non-recursive solution, as a possible improvement (per Reinderien's answer).

The general idea here is that if we build a tree of these strings in the obvious way (i.e. the children are one character extensions of their parents)way*, then the lexicographical ordering is nothing but a DFS on this tree.

*Let the root be the empty string, then its neighbours are the one character long strings for each character of the alphabet, and so on. For example on the alphabet ab with max_length = 2, the tree would look like the following:

<root>
|
+- a
|  |
|  +- aa
|  |
|  `- ab
|
`- b
   |
   +- ba
   |
   `- bb

Then we can sort of build the tree while doing the DFS like so:

def lexstrings(max_length=3, alphabet="ab"):
    reversed_alphabet = list(reversed(alphabet))
    nodes_to_visit = ['']

    while nodes_to_visit:
        current_node = nodes_to_visit.pop()
        
        if len(current_node) > max_length:
            continue

        yield current_node
        nodes_to_visit.extend(current_node + tc for tc in reversed_alphabet)

On a possible non-recursive solution, as a possible improvement (per Reinderien's answer).

The general idea here is that if we build a tree of these strings in the obvious way (i.e. the children are one character extensions of their parents), then the lexicographical ordering is nothing but a DFS on this tree.

def lexstrings(max_length=3, alphabet="ab"):
    reversed_alphabet = list(reversed(alphabet))
    nodes_to_visit = ['']

    while nodes_to_visit:
        current_node = nodes_to_visit.pop()
        
        if len(current_node) > max_length:
            continue

        yield current_node
        nodes_to_visit.extend(current_node + tc for tc in reversed_alphabet)

On a possible non-recursive solution, as a possible improvement (per Reinderien's answer).

The general idea here is that if we build a tree of these strings in the obvious way*, then the lexicographical ordering is nothing but a DFS on this tree.

*Let the root be the empty string, then its neighbours are the one character long strings for each character of the alphabet, and so on. For example on the alphabet ab with max_length = 2, the tree would look like the following:

<root>
|
+- a
|  |
|  +- aa
|  |
|  `- ab
|
`- b
   |
   +- ba
   |
   `- bb

Then we can sort of build the tree while doing the DFS like so:

def lexstrings(max_length=3, alphabet="ab"):
    reversed_alphabet = list(reversed(alphabet))
    nodes_to_visit = ['']

    while nodes_to_visit:
        current_node = nodes_to_visit.pop()
        
        if len(current_node) > max_length:
            continue

        yield current_node
        nodes_to_visit.extend(current_node + tc for tc in reversed_alphabet)
Start the search from the root.
Source Link
Eman Yalpsid
  • 1.6k
  • 11
  • 16

On a possible non-recursive solution, as a possible improvement (per Reinderien's answer).

The general idea here is that if we build a tree of these strings in the obvious way (i.e. the children are one character extensions of their parents), then the lexicographical ordering is nothing but a DFS on this tree.

def lexstrings(max_length=3, alphabet="ab"):
    reversed_alphabet = list(reversed(alphabet))
    nodes_to_visit = list(reversed_alphabet)
['']
    yield ''
    while nodes_to_visit:
        current_node = nodes_to_visit.pop()
        
        if len(current_node) > max_length:
            continue

        yield current_node
        nodes_to_visit.extend(current_node + tc for tc in reversed_alphabet)

On a possible non-recursive solution, as a possible improvement (per Reinderien's answer).

The general idea here is that if we build a tree of these strings in the obvious way (i.e. the children are one character extensions of their parents), then the lexicographical ordering is nothing but a DFS on this tree.

def lexstrings(max_length=3, alphabet="ab"):
    reversed_alphabet = list(reversed(alphabet))
    nodes_to_visit = list(reversed_alphabet)

    yield ''
    while nodes_to_visit:
        current_node = nodes_to_visit.pop()
        
        if len(current_node) > max_length:
            continue

        yield current_node
        nodes_to_visit.extend(current_node + tc for tc in reversed_alphabet)

On a possible non-recursive solution, as a possible improvement (per Reinderien's answer).

The general idea here is that if we build a tree of these strings in the obvious way (i.e. the children are one character extensions of their parents), then the lexicographical ordering is nothing but a DFS on this tree.

def lexstrings(max_length=3, alphabet="ab"):
    reversed_alphabet = list(reversed(alphabet))
    nodes_to_visit = ['']

    while nodes_to_visit:
        current_node = nodes_to_visit.pop()
        
        if len(current_node) > max_length:
            continue

        yield current_node
        nodes_to_visit.extend(current_node + tc for tc in reversed_alphabet)
Source Link
Eman Yalpsid
  • 1.6k
  • 11
  • 16

On a possible non-recursive solution, as a possible improvement (per Reinderien's answer).

The general idea here is that if we build a tree of these strings in the obvious way (i.e. the children are one character extensions of their parents), then the lexicographical ordering is nothing but a DFS on this tree.

def lexstrings(max_length=3, alphabet="ab"):
    reversed_alphabet = list(reversed(alphabet))
    nodes_to_visit = list(reversed_alphabet)

    yield ''
    while nodes_to_visit:
        current_node = nodes_to_visit.pop()
        
        if len(current_node) > max_length:
            continue

        yield current_node
        nodes_to_visit.extend(current_node + tc for tc in reversed_alphabet)