function string = debruijn ( m, n )

%*****************************************************************************80
%
%% debruijn() constructs a de Bruijn sequence.
%
%  Discussion:
%
%    Suppose we have an alphabet of M letters, and we are interested in
%    all possible strings of length N.  If M = 2 and N = 3, then we are
%    interested in the M^N strings:
%
%      000
%      001
%      010
%      011
%      100
%      101
%      110
%      111
%
%    Now, instead of making a list like this, we prefer, if possible, to
%    write a string of letters, such that every consecutive sequence of
%    N letters is one of the strings, and every string occurs once, if
%    we allow wraparound.
%
%    For the above example, a suitable sequence would be the 8 characters:
%
%      00011101(00...
%
%    where we have suggested the wraparound feature by repeating the first
%    two characters at the end.
%
%    Such a sequence is called a de Bruijn sequence.  It can easily be
%    constructed by considering a directed graph, whose nodes are all
%    M^(N-1) strings of length N-1.  A node I has a directed edge to
%    node J (labeled with character K) if the string at node J can
%    be constructed by beheading the string at node I and adding character K.
%
%    In this setting, a de Bruijn sequence is simply an Eulerian circuit
%    of the directed graph, with the edge labels being the entries of the
%    sequence.  In general, there are many distinct de Bruijn sequences
%    for the same parameter M and N.  This program will only find one
%    of them.
%
%  Licensing:
%
%    This code is distributed under the MIT license.
%
%  Modified:
%
%    19 July 2004
%
%  Author:
%
%    John Burkardt
%
%  Input:
%
%    integer M, the number of letters in the alphabet.
%
%    integer N, the number of letters in a codeword.
%
%  Output:
%
%    integer STRING(M^N), a deBruijn string.
%

%
%  Construct the adjacency information.
%
  nnode = m^(n-1);
  nedge = m^n;

  iedge = 0;

  for i = 1 : nnode

    ivec(1:n-1) = index_unrank0 ( n-1, m, i );

    for k = 1 : m
      jvec(1:n-2) = ivec(2:n-1);
      jvec(n-1) = k;
      j = index_rank0 ( n-1, m, jvec );
      iedge = iedge + 1;
      inode(iedge) = i;
      jnode(iedge) = j;
      knode(iedge) = k;
    end

  end
%
%  Determine a circuit.
%
  [ success, trail ] = digraph_arc_euler ( nnode, nedge, inode, jnode );
%
%  The string is constructed from the labels of the edges in the circuit.
%
  string(1:nedge) = knode(trail(1:nedge));

  return
end
