OU blog

Personal Blogs

neil

Got it I think

Visible to anyone in the world
Edited by Neil Anderson, Wednesday, 10 Aug 2011, 15:20

It's a mess, needs optimized, I need to pseudo-overload it and tidy up my messes, but hey, I have a function that composes permutations!

<html>
<head>
<title>Permutation</title>
</head>
<body>
<script type="text/javascript">
/*
Signature:
Array [Array int || int] X int -->boolean
post:
true if the int is in the permutation
*/

function contains(arr, val){
var found = false, over = false, ret = false
var ix = 0;
while(!found && !over){
if(typeof arr[ix] == 'object'){    //a cycle
var subArr = contains(arr[ix], val);
ret = subArr;
found = subArr;
ix++;
}
else{   
if(arr[ix] == val){
ret = true;
found = true;
}
else if(ix++ >= arr.length){
over = true;
}
}
}
return ret;
}


/*
Signature:
Array int X int --> int
Post:
the int after val
the first int in the array if val is the last member of the array
val if the array doesn't contain int
*/

function findNextInCycle(arr, val){
var len = arr.length;
for(var i = 0; i < len; i++){
if(arr[i] == val){ //we have the value
if(i == len - 1){ //end of the permutation return the first
return arr[0];
}
else{ //return the next value
return arr[i + 1];
}
}
}
return val; //val didn't exist in the permutation
}

/*
Signature:
Array [Array int || int] X int --> boolean
Pre:
Either an array of int representing a single cycle
or an array of array(int) with any fixed points excluded
ie [1,2,3] or [[1,3], [2,4]] but not [[1,2], 3, 4]
the last should be [1,2]
Post:
the int after val
the first int in the array if val is the last member of the array
val if the array doesn't contain int
*/

//uses findNextInCycle
function findNextInPerm(arr, val){
if(contains(arr, val)){
for(var i = 0; i < arr.length; i++){
if(typeof arr[i] == 'object'){ //an array hand it off to findNextInCycle
if(contains(arr[i], val)){
return findNextInCycle(arr[i], val);
} //otherwise we carry on through the cycles
}
else{ //hand the whole thing off to findNextInCycle
return findNextInCycle(arr, val);   
}
}
}
else{
return val;
}
}


/*
Signature:
Array [Array int] --> Array int || Array [Array int]
Post:
If the argument contains only a single array it will return that
Otherwise it will return an array with all single length cycles removed
*/

function fixCycles(arr){
if(arr.length == 1){
return arr[0];
}
else{
var ret = [];
for (cycle in arr){
if(arr[cycle].length > 1){
ret.push(arr[cycle]);
}
}
return ret;
}
}



/*
Signature:
Array [Array int || int] X Array [Array int || int] --> Array Array int
Pre:
The arrays must be either of int representing single cycles
or arrays of array(int) with any fixed points excluded
ie for either array [1,2,3] or [[1,3], [2,4]] but not [[1,2], 3, 4]
the last should be [1,2]
Post:
a composition of permutations
Use the fixCycles function to change this into a single permutaion

Note:
We need len because we may not have all numbers may appear in the perms
*/

function composePerms(first, second, len){
var ret = [], cache = [];
for(var i = 1; i <= len; i++){
if(!contains(ret, i)){
var at = i;
while(!contains(cache, at)){
cache.push(at);
at = findNextInPerm(first, findNextInPerm(second, at));
}   
ret.push(cache);
cache = []; //reset
}
}
return ret;       
}

var x = fixCycles(composePerms([1,2,4,3,5], [1,2,3,5,4], 5));
for(i in x){
document.writeln(x[i]);
} //1 4 2 5 3

// -->
</script>
</body>
</html>

Now I need to write the unit tests, and a test suite.

Permalink Add your comment
Share post

Comments

neil

Test

Here's how that's going

<html>
<head>
<title>Test Suite</title>
</head>
<body>
<script type="text/javascript">
boolean
Post:
  I/O Writes the body of the functions and the result of the tests to the standard output
*/

njaTest.harness = function(){
  for(i in njaTest.tests){
   document.write(njaTest.tests[i][0]);
  document.write('-' + njaTest.assert(njaTest.tests[i][0], njaTest.tests[i][1]) + '<br />');
 }
}

/*
Signature:
  function X Array [Array [test, result]] --> boolean
Pre:
  the function to be tested
 an array containing arrays of tuples of the value to test and the required result
Post:
  true if the function all values/test pass
*/

njaTest.assert = function (funct, arr){
  var pass = true;
  for(i in arr){
   if(funct(arr[i][0]) != arr[i][1]){
    pass = false;
   break;
  }
 }
 return pass;
}

/*
  TEST of test stuff
*/

var square = function(x){
  return x * x;
}

var cube = function(x){
  return x * x * x;
}

valsSq = [[2,4],[3,9],[5,25], [8, 64]];
valsCu = [[2,8],[3,27], [5,125]];

njaTest.tests.push([square, valsSq]);
njaTest.tests.push([cube, valsCu]);
njaTest.harness();

// -->
</script>
</body>
</html>

How does one test a test suite?

neil

New comment

argh

There's a rather imortant bit of the above missing because I forgot that --> has a meaning. Don't mess with string!

var njaTest = {}; //namespace

njaTest.tests = []; //function/inputs pairs cache