L
lloyd
So I have a little program that enumerates rectangular arrays of small
integers with a particular property. Each rotation and reflection of a
solution is valid, but when you rotate/reflect, the entries in each
cell of the array are transformed too. I want to enumerate the reduced
count of solutions that have been rotated and reflected into a canonic
form, but I also want to enumerate the larger number of solutions that
include all rotations and reflections as separate. My generating
program will reach all possibilities eventually.
Here's how I do it: I precompute the effect that each of the 8
transformations (combinations of rotation and reflection) will have on
any possible entry (currently there are only 8 possible entries). I
store these in a two-dimensional array T[8][8] where the first index
identifies which transformation we're dealing with and the second is
the "input". For each unreduced array solution that I generate and
hold in the array g[][], I see if I can put it in a lexicographically
lower form by transforming it by each of the transformations; I of
course skip the identity, and I only use the first three
transformations (no 90-degree rotations or reflections across
diagonals) if my array isn't square. As soon as I find a
transformation that is lower, I bail out, because the canonic form is
the lowest lexicographically. If the solution being tested is lower
than (or equal to) all possible transformations, I'm interested in its
degree of symmetry, which I calculate here as dsym (I don't care about
dsym if the solution being tested is in non-canonic form). My
rectangle is given by #DEFINED values B (breadth) and H (height). The
code for this function, which returns NO if we're not in canonic form
and YES if we are, plus it calculates the global variable dsym, is as
follows, and I wonder if anyone sees any significant speed
improvements I could make. Is it possible to do the same without going
through this loop 7 times?? Maybe using seven different flags? Thank
you!
int best_symmetry()
{
int i,j,flag;
dsym=1;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[1][g[H-1-i][j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[2][g[B-1-j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[3][g[H-1-i][B-1-j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
if (H != B) /* stop here if we're not on a square
grid */
return YES;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[4][g[j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[5][g[H-1-j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[6][g[j][H-1-i]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[7][g[H-1-j][H-1-i]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
return YES;
}
integers with a particular property. Each rotation and reflection of a
solution is valid, but when you rotate/reflect, the entries in each
cell of the array are transformed too. I want to enumerate the reduced
count of solutions that have been rotated and reflected into a canonic
form, but I also want to enumerate the larger number of solutions that
include all rotations and reflections as separate. My generating
program will reach all possibilities eventually.
Here's how I do it: I precompute the effect that each of the 8
transformations (combinations of rotation and reflection) will have on
any possible entry (currently there are only 8 possible entries). I
store these in a two-dimensional array T[8][8] where the first index
identifies which transformation we're dealing with and the second is
the "input". For each unreduced array solution that I generate and
hold in the array g[][], I see if I can put it in a lexicographically
lower form by transforming it by each of the transformations; I of
course skip the identity, and I only use the first three
transformations (no 90-degree rotations or reflections across
diagonals) if my array isn't square. As soon as I find a
transformation that is lower, I bail out, because the canonic form is
the lowest lexicographically. If the solution being tested is lower
than (or equal to) all possible transformations, I'm interested in its
degree of symmetry, which I calculate here as dsym (I don't care about
dsym if the solution being tested is in non-canonic form). My
rectangle is given by #DEFINED values B (breadth) and H (height). The
code for this function, which returns NO if we're not in canonic form
and YES if we are, plus it calculates the global variable dsym, is as
follows, and I wonder if anyone sees any significant speed
improvements I could make. Is it possible to do the same without going
through this loop 7 times?? Maybe using seven different flags? Thank
you!
int best_symmetry()
{
int i,j,flag;
dsym=1;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[1][g[H-1-i][j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[2][g[B-1-j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[3][g[H-1-i][B-1-j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
if (H != B) /* stop here if we're not on a square
grid */
return YES;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[4][g[j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[5][g[H-1-j]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[6][g[j][H-1-i]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
flag=0;
for (i=0;i<H;i++) {
for (j=0;j<B;j++) {
flag=g[j]-T[7][g[H-1-j][H-1-i]];
if (flag)
break;
} if (flag)
break;
} if (flag>0)
return NO;
if (flag==0)
dsym++;
return YES;
}