/* Pre: perm is initialized, hist[0..rank-1] is descending. * Create the list of permutations (as powers of 2) * that preserve hist[0..rank-1] */ Arraylist specPerm(int rank, int* hist) { int i, j, k, m, x; Intstack prim = newIntstack(rank, NULL) ; Arraylist result = newArraylist(1) ; Arraylist locperm; prim->size = rank; for (i = 0, x = 1; i < rank; i++, x <<= 1) { prim->it[i] = x; } putItem(prim, result) ; i = 0; while (i + 1 < rank) { j = i+1; while (j < rank && hist[i] == hist[j]) j++; if (i+1 < j) { x = result->size; locperm = getPerm(j-i) ; for (k = 0; k < locperm->size - 1; k++) for (m = 0; m < x; m++) putItem(applyPerm(i, result->it[m], locperm->it[k]), result) ; } i = j; } return result; }
void tests() { // All 1s and all 0's matrix are complements assert(32768 == applyPerm(1, COMP_PERM)); assert(1 == applyPerm(32768, COMP_PERM)); }
void calculateCannonicalIndex() { int i, j, something; int r, v, h, c, r2, r3, t; struct CannonList list; for (i = 0; i < 65536; i++) { CANNONICAL_INDEX[i] = i; OPS_LENGTH[i] = 0; } for (i = 0; i < 65536; i++) { if (CANNONICAL_INDEX[i] == i) { list.length = 1; list.vals[0] = i; do { something = 0; for (j = 0; j < list.length; j++) { r = applyPerm(list.vals[j], ROT_PERM); h = applyPerm(list.vals[j], HORIZ_FLIP_PERM); v = applyPerm(list.vals[j], VERT_FLIP_PERM); c = applyPerm(list.vals[j], COMP_PERM); // r2 = applyPerm(r, ROT_PERM); // r3 = applyPerm(r2, ROT_PERM); something += insert(&list, r); // something += insert(&list, r2); // something += insert(&list, r3); something += insert(&list, h); something += insert(&list, v); something += insert(&list, c); // typedef enum { VERT, HORIZ, COMP, ROT } operation; if (CANNONICAL_INDEX[r] != i) { CANNONICAL_INDEX[r] = i; concatOps(list.vals[j], r, ROT); } if (CANNONICAL_INDEX[h] != i) { CANNONICAL_INDEX[h] = i; concatOps(list.vals[j], h, HORIZ); } if (CANNONICAL_INDEX[v] != i) { CANNONICAL_INDEX[v] = i; concatOps(list.vals[j], v, VERT); } if (CANNONICAL_INDEX[c] != i) { CANNONICAL_INDEX[c] = i; concatOps(list.vals[j], c, COMP); } // CANNONICAL_INDEX[r2] = i; // CANNONICAL_INDEX[r3] = i; // CANNONICAL_INDEX[h] = i; // CANNONICAL_INDEX[v] = i; // CANNONICAL_INDEX[c] = i; } } while (something); for (j = 0; j < list.length; j++) CANNONICAL_INDEX[list.vals[j]] = i; } } }