Skip to content

Instantly share code, notes, and snippets.

@rgov
Last active March 12, 2026 20:17
Show Gist options
  • Select an option

  • Save rgov/891712 to your computer and use it in GitHub Desktop.

Select an option

Save rgov/891712 to your computer and use it in GitHub Desktop.
de Bruijn sequence generator
def deBruijn(n, k):
'''
An implementation of the FKM algorithm for generating the de Bruijn
sequence containing all k-ary strings of length n, as described in
"Combinatorial Generation" by Frank Ruskey.
'''
a = [0] * (n + 1)
out = []
def gen(t, p):
if t > n:
if n % p == 0:
out.extend(a[1:p + 1])
else:
a[t] = a[t - p]
gen(t + 1, p)
for j in range(a[t - p] + 1, k):
a[t] = j
gen(t + 1, t)
gen(1, 1)
return out
@Connor-Irwin
Copy link

A modified version I made:

def deBruijn(n, k):
   '''
   An implementation of the FKM algorithm for generating the de Bruijn
   sequence containing all k-ary strings of length n, as described in
   "Combinatorial Generation" by Frank Ruskey.
   '''
 
   a = [ 0 ] * (n + 1)
   
   def gen(t, p):
      if t > n:
         for v in a[1:p + 1]:
           yield v
      else:
         a[t] = a[t - p]
         
         for v in gen(t + 1, p):
           yield v
         
         for j in range(a[t - p] + 1, k):
            a[t] = j
            for v in gen(t + 1, t):
              yield v
   
   return gen(1, 1)
 
 
if __name__ == '__main__':
   #size of number combinations
   n=4
   
   #which base of numbers to use
   k=2


#be careful editing the stuff in this box
####################################################################
   sequence = ''                                                   #
   alpha_list = [chr(ord('A') + (x - 10)) for x in deBruijn(n, k)] #
   num_list = [str(x) for x in deBruijn(n, k)]                     #
                                                                   #
   for i in range(len(num_list)):                                  #
      if int(num_list[i]) > 9:                                     #
         sequence += alpha_list[i]                                 #
      else:                                                        #
         sequence += num_list[i]                                   #
####################################################################

   #comment and uncomment any section of code below
   #single line output
   print(sequence + '\n\nHuman readable:\n')
   
   #human readable output
   for i in range(len(sequence) - (n - 1)):
      alt_view = ''
      for e in range(n):
         alt_view += sequence[e + i]
      print(alt_view)



   #alphabetical only output
   #print(''.join([chr(ord('A') + x) for x in deBruijn(n, k)]))
   
   #base10 numerical output
   #print(''.join([str(x) for x in deBruijn(n, k)]))

@qiping
Copy link

qiping commented Nov 14, 2023

I run it for (3, 2) and got:
10 :0001010111

Human readable:

000
001
010
101
010
101
011
111
There are 2 '101' but no '100'.

@rgov
Copy link
Author

rgov commented Nov 14, 2023

Nice catch @qiping. Perhaps there is an off by one error. The original source was this document (PDF), chapter 7 -- but this gist is over 12 years old.

@rgov
Copy link
Author

rgov commented Mar 12, 2026

I resolved an issue with a missing condition. With @qiping's test case n=3, k=2, the correct output is 00010111. Note that 100 is missing because the sequence is cyclical. You can use seq + seq[:n-1] to wrap it around and explicitly include the 100 as in 00010111 00.

Verified against the test cases given in Ruskey (2003) and by explicitly checking all combinations are present.

I updated the code to run on Python 3. Turns out generators are slower than just accumulating the output a list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment