PermutationGroup { public List<Permutation> transversal(final PermutationGroup subgroup) { final long m = this.order() / subgroup.order(); final List<Permutation> results = new ArrayList<Permutation>(); Backtracker transversalBacktracker = new Backtracker() { private boolean finished = false; @Override public void applyTo(Permutation p) { for (Permutation f : results) { Permutation h = f.invert().multiply(p); if (subgroup.test(h) == size) { return; } } results.add(p); if (results.size() >= m) { this.finished = true; } } @Override public boolean isFinished() { return finished; } }; this.apply(transversalBacktracker); return results; } PermutationGroup(int size);  PermutationGroup(Permutation base);  PermutationGroup(int size, List<Permutation> generators); static PermutationGroup makeSymN(int size); int getSize(); long order(); Permutation get(int uIndex, int uSubIndex); List<Permutation> getLeftTransversal(int index); List<Permutation> transversal(final PermutationGroup subgroup); void apply(Backtracker backtracker); List<Permutation> all(); void changeBase(Permutation newBase); void enter(Permutation g); int test(Permutation permutation); @Override String toString();  }
@Test public void testTransversal() { int size = 4; PermutationGroup group = PermutationGroup.makeSymN(size); Permutation p1 = new Permutation(2, 1, 0, 3); Permutation p2 = new Permutation(0, 3, 2, 1); List<Permutation> generators = new ArrayList<Permutation>(); generators.add(p1); generators.add(p2); PermutationGroup subgroup = new PermutationGroup(size, generators); List<Permutation> transversal = group.transversal(subgroup); int subgroupOrder = (int) subgroup.order(); int groupOrder = (int) group.order(); int transversalSize = transversal.size(); Assert.assertEquals(factorial(size), groupOrder); Assert.assertEquals(groupOrder / subgroupOrder, transversalSize); }