package classes{
import flash.utils.ByteArray;
public class SingleGroupConstraints {
/*
This class provides a set of read only functions that filter and sort data from the single main set of constraints.
Note that the function "createConstraints2to9()" is quite time consuming and so we only call it once via a stic constructor
All functions and variables are therefore static.
*/
import mx.controls.Alert;
import mx.collections.Sort;
import classes.SingleGroupConstraints;
import mx.collections.SortField;
import mx.collections.XMLListCollection;
public static var groupConstraints:XML= //This contains all combinations for 2 to 9 squares
{
createConstraints2to9();
//Note this is effectively a 'staic' constructor
//see http://www.barneyb.com/barneyblog/2007/11/02/enums-and-actionscripts-static-initializers/
//
// It creates the complete list of constraints
// so that they can be filtered later
// e.g.
// groupConstraints.groupConstraint.(@numberOfSquares==3).XOR.(@total==22) produces the XMLlist below:
/*
5
8
9
6
7
9
*/
}
public static function getDoubleLabelSquareConstraintAsXML(nSquares1:int, sTotal1:int, nSquares2:int, sTotal2:int):XML{
//Return intersection between two label square constraints
var values1:Array=getUniqueNumberListAsArray(nSquares1, sTotal1);
var values2:Array=getUniqueNumberListAsArray(nSquares2, sTotal2);
var r2:XML=;
for (var i1:int=0; i1{values1[i1]};
r2.appendChild(v1);
}
}
}
var values:String="";
for each (var tmp:XML in r2.v) values+=tmp.toString()+",";
r2.@values=values;
return r2;
}
public static function generateRowColumnConstraintAsXML(nSquares:int, sTotal:int):XML{
/*
return example:
8
9
*/
var ret:XML=
var tmp2:XMLList=groupConstraints.groupConstraint.(@numberOfSquares==nSquares).XOR.(@total==sTotal);
for each (var E:XML in tmp2) ret.appendChild(E);
return ret;
}
public static function reduceRowColumnAndSquareConstraintAsXML(constraint:XML):XML{
//Combines a square constraint with a row-column-constraint to a new (reduced)row-column-constraint
//ALGORITHM
//For each 'value' of the square constraint find each row-column constraint that contains 'value'
// and for each of these row-column constraints delete 'value' from it and add to the list of return constraints
var squareConstraints:XMLList=constraint.squareConstraint[0].v;
var rowColConstraint:XMLList=constraint.rowColumnConstraint[0].XOR;
var con:XML=
var addConstraint:Boolean=false;
for each (var vv:XML in squareConstraints) {
var value:String=vv.toString();
for (var i:int=0; i
newXOR.@values=xorValues;
var allCommas:RegExp = /,/g
var noCommas:String=xorValues.replace(allCommas,"");
for (var c:int=0; c {noCommas.charAt(c)}
newXOR.appendChild(vv);
}
con.appendChild(newXOR);
}
}
}
return con;
}
public static function getRawList(nSquares:int, sTotal:int):XMLList{
return groupConstraints.groupConstraint.(@numberOfSquares==nSquares).XOR.(@total==sTotal).@values;
// e.g. allConstraints.getRawList(3,22) gives the XMLList:
// 5,8,9
// 6,7,9
}
public static function getUniqueNumberListAsArray(nSquares:int, sTotal:int):Array {
var tmp:XMLList=groupConstraints.groupConstraint.(@numberOfSquares==nSquares).XOR.(@total==sTotal).v;
return uniqueSort(tmp);
// e.g. allConstraints.getUniqueNumberListAsString(3,22) gives the string:
// 5,6,7,8,9
}
public static function getTotalsAsArray(nSquares:int):Array{
//returns all possible totals of nSquares squares
//can be generated via "return uniqueSort(groupConstraints.groupConstraint.(@numberOfSquares==nSquares).XOR.@total);"
var a:Array = new Array;
switch(nSquares){
case(2): a = [3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]; break;
case(3): a = [6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24]; break;
case(4): a = [10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30]; break;
case(5): a = [15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35]; break;
case(6): a = [21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39]; break;
case(7): a = [28,29,30,31,32,33,34,35,36,37,38,39,40,41,42]; break;
case(8): a = [36,37,38,39,40,41,42,43,44]; break;
case(9): a = [45]; break;
}
return a;
}
private static function uniqueSort(l:XMLList):Array{
//sorts a list and removes non-unique entries
var l2:XMLListCollection=new XMLListCollection(l);
var sort:Sort = new Sort();
sort.fields = [new SortField(null, true, false, true)];
l2.sort=sort;
l2.refresh();
var r:Array=new Array;
var n1:String="";
for each (var element:XML in l2) {
var n:String=element.toString();
if (n!=n1) r.push(n);
n1=n;
}
return r;
}
private static function createConstraints2to9(){
for (var nSquares:int=2; nSquares<=9; nSquares++){
var groupConstraint:XML=
generateCombos(nSquares, groupConstraint)
groupConstraints.appendChild(groupConstraint);
}
}
private static function generateCombos(nSquares:int, groupConstraint:XML):void {
//This is a combinatorics C(r,n) problem = "choose r objects from a group of n objects"
//A recusive function would be much neater but a bit more confusing to code
//as r is restricted to the range (2 to 9 inclusive) its not a problem to write out long hand
var r:int=nSquares;
var c:int=9;
var count:int=1, total:int=0, i:int=0, j:int=0;
var n:Array=[0,1,2,3,4,5,6,7,8,9];
var combination:Array;
switch(r){
case(1): //this case is not actually required
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c; n[1]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
break;
case(2):
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c-1; n[1]++){
for (n[2]=n[1]+1; n[2]<=c; n[2]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
}
break;
case(3):
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c-(r-1); n[1]++){
for (n[2]=n[1]+1; n[2]<=c-(r-2); n[2]++){
for (n[3]=n[2]+1; n[3]<=c-(r-3); n[3]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
}
}
break;
case(4):
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c-(r-1); n[1]++){
for (n[2]=n[1]+1; n[2]<=c-(r-2); n[2]++){
for (n[3]=n[2]+1; n[3]<=c-(r-3); n[3]++){
for (n[4]=n[3]+1; n[4]<=c-(r-4); n[4]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
}
}
}
break;
case(5):
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c-(r-1); n[1]++){
for (n[2]=n[1]+1; n[2]<=c-(r-2); n[2]++){
for (n[3]=n[2]+1; n[3]<=c-(r-3); n[3]++){
for (n[4]=n[3]+1; n[4]<=c-(r-4); n[4]++){
for (n[5]=n[4]+1; n[5]<=c-(r-5); n[5]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
}
}
}
}
break;
case(6):
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c-(r-1); n[1]++){
for (n[2]=n[1]+1; n[2]<=c-(r-2); n[2]++){
for (n[3]=n[2]+1; n[3]<=c-(r-3); n[3]++){
for (n[4]=n[3]+1; n[4]<=c-(r-4); n[4]++){
for (n[5]=n[4]+1; n[5]<=c-(r-5); n[5]++){
for (n[6]=n[5]+1; n[6]<=c-(r-6); n[6]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
}
}
}
}
}
break;
case(7):
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c-(r-1); n[1]++){
for (n[2]=n[1]+1; n[2]<=c-(r-2); n[2]++){
for (n[3]=n[2]+1; n[3]<=c-(r-3); n[3]++){
for (n[4]=n[3]+1; n[4]<=c-(r-4); n[4]++){
for (n[5]=n[4]+1; n[5]<=c-(r-5); n[5]++){
for (n[6]=n[5]+1; n[6]<=c-(r-6); n[6]++){
for (n[7]=n[6]+1; n[7]<=c-(r-7); n[7]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
}
}
}
}
}
}
break;
case(8):
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c-(r-1); n[1]++){
for (n[2]=n[1]+1; n[2]<=c-(r-2); n[2]++){
for (n[3]=n[2]+1; n[3]<=c-(r-3); n[3]++){
for (n[4]=n[3]+1; n[4]<=c-(r-4); n[4]++){
for (n[5]=n[4]+1; n[5]<=c-(r-5); n[5]++){
for (n[6]=n[5]+1; n[6]<=c-(r-6); n[6]++){
for (n[7]=n[6]+1; n[7]<=c-(r-7); n[7]++){
for (n[8]=n[7]+1; n[8]<=c-(r-8); n[8]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
}
}
}
}
}
}
}
break;
case(9):
groupConstraint.@numberOfSquares=r;
for (n[1]=1; n[1]<=c-(r-1); n[1]++){
for (n[2]=n[1]+1; n[2]<=c-(r-2); n[2]++){
for (n[3]=n[2]+1; n[3]<=c-(r-3); n[3]++){
for (n[4]=n[3]+1; n[4]<=c-(r-4); n[4]++){
for (n[5]=n[4]+1; n[5]<=c-(r-5); n[5]++){
for (n[6]=n[5]+1; n[6]<=c-(r-6); n[6]++){
for (n[7]=n[6]+1; n[7]<=c-(r-7); n[7]++){
for (n[8]=n[7]+1; n[8]<=c-(r-8); n[8]++){
for (n[9]=n[8]+1; n[9]<=c-(r-9); n[9]++){
combination = new Array;
total=0;
var c1:XML =
for(i=1; i<=r; i++) {
var v1:XML={n[i]}
c1.appendChild(v1);
combination[i-1]=n[i]; total+=n[i];
}
count+=1;
c1.@values=combination.toString();
c1.@total=total.toString();
groupConstraint.appendChild(c1);
}
}
}
}
}
}
}
}
}
break;
default:
Alert.show("Sorry: can't do combinations above 9 from C", "Restriction");
break;
}
}
/* EXAMPLES
private var cons:SingleGroupConstraints=new SingleGroupConstraints;
var tmp:XMLList=cons.groupConstraints.groupConstraint.(@numberOfSquares==2).XOR.(@total==6);
gives:
...
...
*/
//var tmp2:XMLList=tmp[0].XOR.(@total==6);
/* gives:
*/
//outputText.text+="\n2 Squares that total 6:\n"+tmp2.toString()+"\n\n";
//var tmp3:XMLList=cons.groupConstraints.groupConstraint.(@numberOfSquares==2).XOR.(@total==6).@values;
/* gives:
1,52,4 (=1,5 2,4)
*/
//outputText.text+="\n2 Squares that total 6:\n"+tmp3.toString()+"\n\n";
//for (var i:int=0; i