Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Nurdok committed Sep 20, 2011
0 parents commit d4298dc
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .classpath
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
<classpathentry kind="output" path="bin"/>
</classpath>
17 changes: 17 additions & 0 deletions .project
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Permutation</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
12 changes: 12 additions & 0 deletions .settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,12 @@
#Fri Sep 16 18:24:57 IDT 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6
140 changes: 140 additions & 0 deletions src/permutations/PermutationGenerator.java
@@ -0,0 +1,140 @@
package permutations;

import java.util.Collections;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

public class PermutationGenerator<T> implements Iterator<List<T>>, Iterable<List<T>> {

private final List<T> permutationObjects;
private final int permutationSize;
private int currentPermutationIndex = -1; //TODO: think about numbering
private final int lastPermutationIndex;
private final List<T> permutation;

public PermutationGenerator(final List<T> list) {
this.permutationObjects = list;
this.permutationSize = list.size();
this.lastPermutationIndex = factorial(permutationSize);
permutation = new LinkedList<T>();
permutation.addAll(list);
}

public List<T> getPermutation(final int index) {
final PermutationGenerator<T> pg = new PermutationGenerator<T>(permutationObjects);
List<T> permutationByIndex = null;
for (int i=0; i<index; ++i) {
permutationByIndex = pg.next();
}
return permutationByIndex;
}

//TODO: replace with fast implementation
public int factorial(final int n) {
return (n == 1) ? 1 : factorial(n-1) * n;
}

@Override
public boolean hasNext() {
if (currentPermutationIndex < lastPermutationIndex) {
return true;
}
return false;
}

@Override
public List<T> next() {
currentPermutationIndex++;
if (currentPermutationIndex == 0) {
return permutation;
}

//Find the largest index k such that a[k] < a[k + 1].
final int k = findMaxK();
if (k == -1) {
throw new RuntimeException("Called next when there are no more permutations");
}

//Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l.
final int l = findMaxL(k);

//Swap a[k] with a[l].
swap(k,l);

//Reverse the sequence from a[k + 1] up to and including the final element a[n].
reverseFrom(k+1);

return permutation;
}

private List<T> permutationByIndex(int index)
{
final List<T> permutation = new LinkedList<T>();
int r = 1, m;
for(int i = 0; i < permutationSize; i++) {
permutation.set(i, permutationObjects.get(i));
}

while (r < permutationSize)
{
m = index%(r+1);
index = index/(r+1);
final T temp = permutation.get(r);
permutation.set(r, permutation.get(m));
permutation.set(m, temp);
r++;
}
return permutation;
}

private void reverseFrom(final int i) {
Collections.reverse(permutation.subList(i, permutationSize));
}

private void swap(final int k, final int l) {
final T tK = permutation.get(k);
final T tL = permutation.get(l);
permutation.set(l, tK);
permutation.set(k, tL);
}

//Find the largest index l such that a[k] < a[l]. Since k + 1 is such an index, l is well defined and satisfies k < l.
private int findMaxL(final int k) {
int l = k+1;
final T tK = permutation.get(k);
for (int i=k+1; i<permutationSize; ++i) {
final T tL= permutation.get(i);
if (permutationObjects.indexOf(tK) < permutationObjects.indexOf(tL)) {
l = i;
}
}
return l;
}

private int findMaxK() {
int k = -1;
for (int i=0; i<permutationSize-1; ++i) {
final T tK = permutation.get(i);
final T tKNext= permutation.get(i+1);
if (permutationObjects.indexOf(tK) < permutationObjects.indexOf(tKNext)) {
k = i;
}
}
return k;
}

@Override
public void remove() {
throw new UnsupportedOperationException();
}

@Override
public Iterator<List<T>> iterator() {
return this;
}

public List<T> get(final int index) {
return permutationByIndex(index);
}
}
43 changes: 43 additions & 0 deletions src/tests/PermutationGeneratorTest.java
@@ -0,0 +1,43 @@
/**
*
*/
package tests;

import static org.junit.Assert.fail;

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

import org.junit.Before;
import org.junit.Test;

import permutations.PermutationGenerator;

/**
* @author Rachum
*
*/
public class PermutationGeneratorTest {

private PermutationGenerator<String> pg;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
pg = new PermutationGenerator<String>(Arrays.asList("a", "b", "c"));
}

/**
* Test method for {@link permutations.PermutationGenerator#next()}.
*/
@Test
public void testNext() {
for (final List<String> permutation : pg) {
System.out.println(permutation);
}
System.out.println(pg.get(3));
fail("Not yet implemented"); // TODO
}

}

0 comments on commit d4298dc

Please sign in to comment.