/*
 * DirectedAcyclicWordGraph.java
 *
 * Copyright (C) 2017 [ A Legge Up ] <stephen@aleggeup.com>
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

package com.aleggeup.confagrid.words;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;

public class DirectedAcyclicWordGraph {

    private final WordList wordList;
    private final int verticiesCount;
    private final List<List<Integer>> adjacentVerticies;
    private final int[] indegrees;
    private final int[] ranks;

    private int edgesCount;

    public DirectedAcyclicWordGraph(final WordList wordList) {
        this.wordList = wordList;
        verticiesCount = wordList.size();
        edgesCount = 0;
        adjacentVerticies = new ArrayList<List<Integer>>();
        indegrees = new int[verticiesCount];
        ranks = new int[verticiesCount];

        for (int i = 0; i < verticiesCount; ++i) {
            adjacentVerticies.add(new ArrayList<Integer>());
        }
    }

    protected void addEdgesFromPhrase(final Phrase phrase) {
        Word tail = null;
        for (final Iterator<Word> iterator = phrase.iterator(); iterator.hasNext();) {
            final Word word = iterator.next();
            if (tail == null) {
                tail = word;
            } else {
                addEdge(tail, word);
                tail = word;
            }
        }
    }

    protected void addEdge(final Word tail, final Word head) {
        final int tailId = wordList.getWordId(tail);
        final int headId = wordList.getWordId(head);
        if (!adjacentVerticies.get(tailId).contains(Integer.valueOf(headId))) {
            adjacentVerticies.get(tailId).add(Integer.valueOf(headId));
            ++indegrees[headId];
            ++edgesCount;
        }
    }

    protected boolean hasOrder() {
        final Deque<Integer> queue = new ArrayDeque<>();
        final Deque<Integer> order = new ArrayDeque<>();
        final int[] indegreesDiff = new int[verticiesCount];
        final int[] groups = new int[verticiesCount];

        for (int i = 0; i < verticiesCount; ++i) {
            indegreesDiff[i] = indegrees[i];
        }

        for (int i = 0; i < verticiesCount; ++i) {
            if (indegreesDiff[i] == 0) {
                queue.push(i);
            }
        }

        int count = 0;
        int group = 0;
        while (!queue.isEmpty()) {
            final int value = queue.pop().intValue();
            order.push(value);
            ranks[value] = count++;
            groups[value] = group;

            boolean newGroup = false;
            for (final Integer v : adjacentVerticies.get(value)) {
                indegreesDiff[v.intValue()]--;
                if (indegreesDiff[v.intValue()] == 0) {
                    newGroup = true;
                    queue.push(v);
                }
            }

            if (newGroup) {
                group++;
            }
        }

        for (int i = 0; i < verticiesCount; ++i) {
            System.out.println(String.format("%d: %d -- %s", i, groups[i], wordList.getReverseLookup()[i].toString()));
        }

        return count == verticiesCount;
    }

    public int getVerticiesCount() {
        return verticiesCount;
    }

    public int getEdgesCount() {
        return edgesCount;
    }
}

@@ -2100,32 +2100,936 @@
 verticiesCount%5D;
+%0A%0A        for (int i = 0; i %3C verticiesCount; ++i) %7B%0A            indegreesDiff%5Bi%5D = indegrees%5Bi%5D;%0A        %7D%0A%0A        for (int i = 0; i %3C verticiesCount; ++i) %7B%0A            if (indegreesDiff%5Bi%5D == 0) %7B%0A                queue.push(i);%0A            %7D%0A        %7D%0A%0A        int count = 0;%0A        while (!queue.isEmpty()) %7B%0A            final int value = queue.pop().intValue();%0A            order.push(value);%0A%0A            for (final Integer v : adjacentVerticies.get(value)) %7B%0A                indegreesDiff%5Bv.intValue()%5D--;%0A                if (indegreesDiff%5Bv.intValue()%5D == 0) %7B%0A                    queue.push(v);%0A                %7D%0A            %7D%0A        %7D%0A%0A        return count == verticiesCount;%0A    %7D%0A%0A    protected int%5B%5D getGroups() %7B%0A        final Deque%3CInteger%3E queue = new ArrayDeque%3C%3E();%0A        final Deque%3CInteger%3E order = new ArrayDeque%3C%3E();%0A        final int%5B%5D indegreesDiff = new int%5BverticiesCount%5D;
 %0A        final i
@@ -3964,220 +3964,21 @@
     
-for (int i = 0; i %3C verticiesCount; ++i) %7B%0A            System.out.println(String.format(%22%25d: %25d -- %25s%22, i, groups%5Bi%5D, wordList.getReverseLookup()%5Bi%5D.toString()));%0A        %7D%0A%0A        return count == verticiesCount
+return groups
 ;%0A  

Split out grouping into a new method so that they can be returned