Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

more tests

  • Loading branch information...
commit a3d799f0b497e3818d3d40c8d99d8476d7e115f3 1 parent acc58a3
@egze authored
View
3  .gitignore
@@ -1 +1,2 @@
-.DS\_Store
+.DS\_Store
+.DS_Store
View
0  dist/permutation-js.js
No changes.
View
28 src/comparable.js
@@ -0,0 +1,28 @@
+var Comparable = {
+ lt: function(object) {
+ return this.compareTo(object) == -1;
+ },
+ lte: function(object) {
+ return this.compareTo(object) < 1;
+ },
+ gt: function(object) {
+ return this.compareTo(object) == 1;
+ },
+ gte: function(object) {
+ return this.compareTo(object) > -1;
+ },
+ eq: function(object) {
+ return this.compareTo(object) == 0;
+ }
+};
+
+Array.prototype.compare = function(testArr) {
+ if (this.length != testArr.length) return false;
+ for (var i = 0; i < testArr.length; i++) {
+ if (this[i].compare) {
+ if (!this[i].compare(testArr[i])) return false;
+ }
+ if (this[i] !== testArr[i]) return false;
+ }
+ return true;
+}
View
139 src/permutation.js
@@ -1,14 +1,93 @@
+Number.prototype.mod = function(n) {
+ return ((this%n)+n)%n;
+}
+
+Number.prototype.hash = function() {
+ var key = this;
+ key += (key << 12);
+ key ^= (key >> 22);
+ key += (key << 4);
+ key ^= (key >> 9);
+ key += (key << 10);
+ key ^= (key >> 2);
+ key += (key << 7);
+ key ^= (key >> 12);
+ return key;
+}
+
var Permutation = Class.create({
initialize: function(size, rank){
this.size = size;
this.rank = rank || 0;
- this.collection = [];
+ this.collection = null;
this.last = this.factorial(size) - 1;
},
+ project: function(data){
+ var collection_data = data || this.collection;
+ if(collection_data == null) return "";
+ if(collection_data.length != this.size) return "";
+ var projection = new Array(collection_data.length);
+ this.value().each(function(i, j){
+ projection[j] = collection_data[i];
+ });
+ if(Object.isString(collection_data)){
+ return $A(projection).join("");
+ } else {
+ return projection;
+ }
+ },
+
+ _each: function(iterator) {
+ for(var r = 0; r <= this.last; r++){
+ var klon = Object.clone(this);
+ klon.setRank(r);
+ iterator(klon);
+ }
+ },
+
+ doEach: function(iterator){
+ var old_rank = this.rank;
+ for(var r = 0; r <= this.last; r++){
+ this.setRank(r);
+ iterator(this);
+ }
+ this.setRank(old_rank);
+ },
+
+ doNext: function(){
+ this.setRank(this.rank + 1);
+ if(this.rank > this.last) this.setRank(0);
+ return this;
+ },
+
+ next: function(){
+ return Object.clone(this).doNext();
+ },
+
+ succ: function(){
+ return this.next();
+ },
+
+ doPred: function(){
+ this.setRank(this.rank - 1);
+ if(this.rank < 0) this.setRank(this.last);
+ return this;
+ },
+
+ pred: function(){
+ return Object.clone(this).doPred();
+ },
+
setRank: function(m){
- this.rank = m % this.factorial(this.size);
+ this.rank = m.mod(this.factorial(this.size));
+ },
+
+ compareTo: function(other){
+ if(this.rank < other.rank){ return -1 }
+ if(this.rank > other.rank){ return 1 }
+ return 0;
},
factorial: function(n){
@@ -18,10 +97,14 @@ var Permutation = Class.create({
return Permutation.fcache[n];
},
+ hash: function(){
+ return this.size.hash() ^ this.rank.hash()
+ },
+
signum: function(){
var s = 1;
cycles.each(function(c){
- if(c.length % 2 == 0){
+ if(c.length.mod(2) == 0){
s = s * -1;
}
});
@@ -46,7 +129,7 @@ var Permutation = Class.create({
});
for(var i = 0; i < this.size; i++){
var f = this.factorial(i);
- var x = m % (f * (i+1));
+ var x = m.mod((f * (i+1)));
m = m - x;
x = x / f;
result[this.size - i - 1] = x;
@@ -65,9 +148,9 @@ var Permutation = Class.create({
doInvert: function(){
var indices = this.unrank_indices(this.rank);
var inverted = new Array(this.size);
- for(var i = 0; i <= this.size; i++){
- inverted[indices[i]] = i;
- }
+ for(var i = 0; i <= this.size; i++){
+ inverted[indices[i]] = i;
+ }
this.setRank(this.rank_indices(inverted));
return this;
},
@@ -80,19 +163,31 @@ var Permutation = Class.create({
klon.setRank(this.rank_indices(composed));
return klon;
},
-
- toArray: function(){
- return [Object.clone(this)];
- },
-
- eql: function(other){
- return this.size == other.size && this.rank == other.rank;
- },
+
+ toArray: function(){
+ var ary = [];
+ this.each(function(o){ ary.push(o)});
+ return ary;
+ },
+
+ eql: function(other){
+ return this.size == other.size && this.rank == other.rank;
+ },
invert: function(){
return Object.clone(this).doInvert();
},
+ doRandom: function(){
+ var new_rank = Math.floor(Math.random()*(this.last + 1));
+ this.setRank(new_rank);
+ return this;
+ },
+
+ random: function(){
+ return Object.clone(this).doRandom();
+ },
+
cycles: function(){
var perm = this.value();
var result = [[]];
@@ -110,7 +205,7 @@ var Permutation = Class.create({
current = perm[current];
}
}
- result.pop();
+ result.pop();
return result.select(function(c){ return c.length > 1}).map(function(c){
var min_index = c.indexOf(c.min());
return c.slice(min_index, c.length).concat(c.slice(0, min_index));
@@ -120,17 +215,7 @@ var Permutation = Class.create({
});
Object.extend(Permutation.prototype, Enumerable);
-
-Object.extend(Permutation.prototype, {
- _each: function(iterator) {
- for(var r = 0; r <= this.last; r++){
- var klon = Object.clone(this);
- klon.setRank(r);
- iterator(klon);
- }
- }
-});
-
+Object.extend(Permutation.prototype, Comparable);
Permutation.fcache = [ 1 ];
View
158 test/unit/permutation_test.html
@@ -6,6 +6,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<script src="../assets/jsunittest.js" type="text/javascript"></script>
<script src="../../src/ext/prototype-1.6.0.3.js" type="text/javascript"></script>
+ <script src="../../src/comparable.js" type="text/javascript"></script>
<script src="../../src/permutation.js" type="text/javascript"></script>
<link rel="stylesheet" href="../assets/unittest.css" type="text/css" />
@@ -30,7 +31,7 @@
<script type="text/javascript">
// <![CDATA[
-
+ //console.log = function(){};
var PERMS = $R(0, 4).map(function(i){ return new Permutation(i) });
var PERMS_COLLECTIONS = ["", "a", "ab", "abc", "abcd"].map(function(c){ return Permutation.for_value(c) });
var PERMS_EACH = $A([
@@ -98,34 +99,157 @@
},
+ testCreated: function() { with(this) {
+ var factorial = 1;
+ PERMS.each(function(p, i){
+ assertEqual(i, p.size)
+ assertEqual(factorial - 1, p.last)
+ factorial *= (i + 1)
+ });
+ }},
+
+ testRankAssign: function() { with(this) {
+ var perm = new Permutation(3);
+ var perms = [
+ [0, 1, 2],
+ [0, 2, 1],
+ [1, 0, 2],
+ [1, 2, 0],
+ [2, 0, 1],
+ [2, 1, 0],
+ [0, 1, 2],
+ ];
+ for(var i = -12; i < -6; i++){
+ perm.setRank(i);
+ assertEnumEqual(perms[i + 12], perm.value());
+ }
+ for(var i = -6; i < 0; i++){
+ perm.setRank(i);
+ assertEnumEqual(perms[i + 6], perm.value());
+ }
+ for(var i = 0; i < 6; i++){
+ perm.setRank(i);
+ assertEnumEqual(perms[i], perm.value());
+ }
+ for(var i = 6; i < 12; i++){
+ perm.setRank(i);
+ assertEnumEqual(perms[i - 6], perm.value());
+ }
+ for(var i = 12; i < 17; i++){
+ perm.setRank(i);
+ assertEnumEqual(perms[i - 12], perm.value());
+ }
+ }},
+
+ testCompare: function() { with(this) {
+ var perm1 = new Permutation(3);
+ var perm2 = new Permutation(3);
+ var perm3 = Object.clone(perm1);
+ var perm4 = new Permutation(3, 1);
+ assert(perm1 != perm2);
+ assert(perm1.eql(perm2));
+ assertEqual(0, perm1.compareTo(perm2));
+ assertEqual(perm1.hash(), perm2.hash());
+ assert(perm1 != perm3);
+ assert(perm1.eql(perm3));
+ assertEqual(0, perm1.compareTo(perm3));
+ assertEqual(perm1.hash(), perm3.hash());
+ assert(!perm1.eql(perm4));
+ assert(perm1 != perm4);
+ assert(!perm1.eql(perm4));
+ assertEqual(-1, perm1.compareTo(perm4));
+ assertEqual(1, perm4.compareTo(perm1));
+ assert(perm1.lt(perm4));
+ assert(perm4.gt(perm1));
+ assert(perm1.hash() != perm4.hash());
+ var perms = perm1.toArray();
+ perms.slice(1, perms.length -1).each(function(p, i){
+ assert(p.gt(perms[i]));
+ assertEqual(1, p.compareTo(perms[i]));
+ assert(perms[i].lt(p));
+ assertEqual(-1, perms[i].compareTo(p));
+ });
+ }},
+
+ testRandom: function() { with(this) {
+ PERMS_EACH.each(function(perms, i){
+ var perm = new Permutation(i);
+ while(perms.length != 0){
+ var deleted = perm.random().value();
+ perms = perms.map(function(e){ if(deleted != e && !deleted.compare(e)) {return e;} }).compact();
+ if(deleted != null && !Object.isUndefined(deleted)) assert(true);
+ }
+ });
+ }},
+
+ testEnumerable: function() { with(this) {
+ PERMS.each(function(perm, i){
+ assertEnumEqual(PERMS_EACH[i], perm.map(function(x){ return x.value() }));
+ });
+ PERMS.each(function(perm, i){
+ var ary = [];
+ var old_rank = perm.rank;
+ perm.doEach(function(x){
+ ary.push(x.value());
+ });
+ assertEnumEqual(PERMS_EACH[i], ary);
+ assertEqual(old_rank, perm.rank);
+ });
+ }},
+
+ testNext: function(){ with(this) {
+ NEXT_PRED.each(function(pred){
+ var before = pred[0], after = pred[1];
+ var beforep = Permutation.from_value(before);
+ var afterp = Permutation.from_value(after);
+ assert(afterp.eql(beforep.next()));
+ assert(beforep.eql(afterp.pred()));
+ assert(afterp.eql(beforep.succ()));
+ });
+ }},
+
+ testProject: function(){ with(this) {
+ var too_big = new Array(10);
+ PERMS.each(function(perms, i){
+ assertEnumEqual(PROJECTED[i], perms.map(function(p){ return p.project(PROJECTED[i][0])}));
+ });
+ PERMS_COLLECTIONS.each(function(perms, i){
+ assertEnumEqual(PROJECTED[i], perms.map(function(p){ return p.project()}));
+ });
+ }},
+
+
+
+
+
testInvert: function() { with(this) {
PERMS.each(function(perm){
var id = perm;
perm.each(function(p){
- assertEnumEqual(id.value(), (p.compose(p.invert())).value());
+ assertEnumEqual(id.value(), (p.compose(p.invert())).value());
assertEnumEqual(id, p.compose(p.invert()));
- assertEnumEqual(id.value(), p.compose(p.invert()).value());
+ assertEnumEqual(id.value(), p.compose(p.invert()).value());
});
});
}},
-
- testCycles: function() { with(this) {
+
+ testCycles: function() { with(this) {
PERMS.each(function(perm, i){
- console.log(CYCLES[i], ":::", perm.map(function(p){ return p.cycles()}));
- assertEnumEqual(CYCLES[i], perm.map(function(p){ return p.cycles() }));
+ //console.log(CYCLES[i], ":::", perm.map(function(p){ return p.cycles()}));
+ assertEnumEqual(CYCLES[i], perm.map(function(p){ return p.cycles() }));
});
}},
-
- testCompose: function() { with(this) {
+
+ testCompose: function() { with(this) {
var too_big = new Permutation(10);
- PERMS.slice(0, 3).each(function(perm){
- var elements = perm.toArray();
- for(var i = 0; i < elements.length; i++){
- for(var j = 0; j < elements.length; j++){
-
- }
- }
- });
+ PERMS.slice(0, 3).each(function(perm){
+ var elements = perm.toArray();
+ for(var i = 0; i < elements.length; i++){
+ for(var j = 0; j < elements.length; j++){
+
+ }
+ }
+ });
}},
}, {testLog: "testlog"});

0 comments on commit a3d799f

Please sign in to comment.
Something went wrong with that request. Please try again.