package nl.dvberkel.dyck;

import java.util.Arrays;
import java.util.List;

public class Generator {
    private final List<String> symbols;
    private final String target;
    private final String replacement;

    public Generator(){
        this("1", "2");
    }

    public Generator(String left, String right) {
        this.symbols = Arrays.asList(left, right);
        this.target = symbols.get(1) + symbols.get(0);
        this.replacement = symbols.get(0) + symbols.get(1);
    }

    /**
     * Return a {code }
     *
     * @param state
     * @return
     * @see <a href="http://arxiv.org/abs/1002.2625">Generating and Ranking of Dyck Words</a>
     */
    public State next(State state) {
        int currentLength = state.word().length();
        do {
            if (state.index() < state.word().length()) {
                int j = state.index();
                while (j < (state.word().length() - 1) && !state.word().substring(j, j + 2).equals(target)) {
                    j++;
                }
                if (j < (state.word().length() - 1)) {
                    String word = state.word();
                    String nextWord = word.substring(0, j) + replacement + word.substring(j+2);
                    return state.update(j + 2).push(nextWord, j - 1);
                }
            }
            state = state.pop();
        } while(state != null);
        return new State(initialWordOfLength(currentLength + 2), 0);
    }

    private String initialWordOfLength(int n) {
        StringBuilder builder = new StringBuilder();
        for (int index = 0; index < n; index++) {
            builder.append(symbols.get(index % 2));
        }
        return builder.toString();
    }

}

@@ -510,59 +510,460 @@
 urn 
-a
+the next %7B@code State%7D after
  %7B
+@
 code 
-%7D%0A     *%0A     * @param state%0A     * @return
+state%7D as determined by the an algorithm found in%0A     * %3Ca href=%22http://arxiv.org/abs/1002.2625%22%3EGenerating and Ranking of Dyck Words%3C/a%3E.%0A     *%0A     * The returned state is meant to be fed into this method again to for a continuous stream of %7B@code State%7Ds.%0A     *%0A     * @param state the %7B@code State%7D that is used as a starting ground for the algorithm.%0A     * @return the %7B@code State%7D following %7B@code state%7D.
 %0A   

Create JavaDoc