/* the Euler algorithm */

        public void shuffle1(char[] s, int l, int k)
        {
            int i, n_lets;

            s_ = s;
            l_ = l;
            k_ = k;
            if (k_ >= l_ || k_ <= 1) /* two special cases */
            {
                return;
            }

            /* use hashtable to find distinct vertices */
            n_lets     = l_ - k_ + 2; /* number of (k-1)-lets */
            n_vertices = 0;
            hinit(n_lets);
            for (i = 0; i < n_lets; i++)
            {
                hinsert(i);
            }
            root     = entries[n_lets - 1].i_vertices; /* the last let */
            vertices = new vertex[n_vertices];
            for (i = 0; i < n_vertices; i++)
            {
                vertices[i] = new vertex();
            }

            /* set i_sequence and n_indices for each vertex */
            for (i = 0; i < n_lets; i++)
            { /* for each let */
                hentry ev = entries[i];
                vertex v  = vertices[ev.i_vertices];

                v.i_sequence = ev.i_sequence;
                if (i < n_lets - 1) /* not the last let */
                {
                    v.n_indices++;
                }
            }

            /* allocate indices for each vertex */
            for (i = 0; i < n_vertices; i++)
            { /* for each vertex */
                vertex v = vertices[i];

                v.indices = new int[v.n_indices];
            }

            /* populate indices for each vertex */
            for (i = 0; i < n_lets - 1; i++)
            { /* for each edge */
                hentry eu = entries[i];
                hentry ev = entries[i + 1];
                vertex u  = vertices[eu.i_vertices];

                u.indices[u.i_indices++] = ev.i_vertices;
            }
            hcleanup();
        }
 private void hinit(int size)
 {
     entries = new hentry[size];
     for (int i = 0; i < size; i++)
     {
         entries[i] = new hentry();
     }
     htable     = new hentry[size];
     htablesize = size;
     hmagic     = (Math.Sqrt(5.0) - 1.0) / 2.0;
 }
        private void hinsert(int i_sequence)
        {
            int    code = hcode(i_sequence);
            hentry e, e2 = entries[i_sequence];

            for (e = htable[code]; e != null; e = e.next)
            {
                if (strncmp(e.i_sequence, i_sequence, k_ - 1) == 0)
                {
                    e2.i_sequence = e.i_sequence;
                    e2.i_vertices = e.i_vertices;
                    return;
                }
            }
            e2.i_sequence = i_sequence;
            e2.i_vertices = n_vertices++;
            e2.next       = htable[code];
            htable[code]  = e2;
        }