Skip to content

Instantly share code, notes, and snippets.

@chochos
Created September 2, 2015 03:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chochos/1a2eb96803fccc06d834 to your computer and use it in GitHub Desktop.
Save chochos/1a2eb96803fccc06d834 to your computer and use it in GitHub Desktop.
Permutator in Ceylon
shared class Permutator<out Element>({Element*} source) satisfies Iterable<{Element*}> {
shared actual Iterator<{Element*}> iterator() {
value elems = source.sequence();
if (elems.size>1) {
value arr = Array(source);
value idxs = Array(0..arr.size);
void swap(Integer i, Integer j) {
if (exists ei=arr[i], exists ej=arr[j]) {
arr.set(i,ej);
arr.set(j,ei);
}
}
object iter satisfies Iterator<{Element*}> {
variable value first=true;
shared actual {Element*}|Finished next() {
if (first) {
first=false;
return source;
}
variable value i=arr.size-1;
while (exists sw=idxs[i]) {
if (i>=0 && sw==arr.size-1) {
swap(i,sw);
idxs.set(i,i);
i--;
} else {
break;
}
}
if (i<0) {
return finished;
} else {
if (exists prev=idxs[i]) {
swap(i,prev);
value next = prev+1;
idxs.set(i, next);
swap(i,next);
}
return arr.sequence();
}
}
}
return iter;
} else {
object iter1 satisfies Iterator<{Element*}> {
variable value done = false;
shared actual {Element*}|Finished next() {
if (done) { return finished; }
done = true;
return source.sequence();
}
}
return iter1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment