#include #include #include #include #include #define Pi3(c, i) ((c/ThreeUp[i])%3) #define Pi(c, i) ((c/NUp[i])%N) #define PiNp(c, i) ((c/NpUp[i])%(N+1)) #define IotaPlus(c, i) ((N*(c/NUp[i])+N-1)*NUp[i]+c%NUp[i]) typedef char little; // intended to hold values up to N*N typedef short medium; // intended to hold values up to N*2^N typedef int large; // intended to hold values up to N^2*N^N struct clash_data { large b,c; }; struct value { double val; int clashes; }; little N=3; medium TwoUpN=8; medium *TwoUp; // {1,2,4,8,...,2^N} large ThreeUpN=27; large *ThreeUp; // {1,3,9,...,3^N} large NmUpN=8; large *NmUp; // @N=3: {1,2,4,8} large NUpN=27; large *NUp; // @N=3: {1,3,9,27} large NpUpN=64; large *NpUp; // @N=3: {1,4,16,64} little *SumOfDigitsModNp; // Sum Of Digits of a base N+1 number of // N digits. int **Binomial; // The binomial coefficients large *order; // The order type of all N^N sums of // edge-lengths. int verbose=1; // verbose level double T=1.; // simulated annealing temperature double CF=1.; // Cooling Factor int ladino_only=1; // Restrict to ladino squares? int compute_ladino_failure=0; // Compute Ladino Failure? int minimal_clash_dimension=0; // Begin testing at clashes of this dimension. large *default_order(); void read_cube(little **cube); void print_cube(little **cube); void copy_cube(little **src, little **dest); void compute_coords(little **cube, large **corners, large **tops); void print_corners(large **corners); void print_tops(large **tops); void make_checklist( large **corners, large **tops, int *cl_lens, large ***cl_low, large ***cl_high, clash_data **cl_cdata ); value evaluate( int *cl_lens, large ***cl_low, large ***cl_high, clash_data **cl_cdata, int pc ); void box_rotate(little **cube, large c, little a, little b); void plane_swap(little **cube, little ind, little a, little b); large ouroboros_move(little **cube, large start, little a, little b); int main(int argc, char *argv[]) { int L=0; // Number of attempts. int read_stdin=0; // Read cube from stdin? int plane_swap_priority=10; int ouroboros_move_priority=10; int use_xor_configuration = 0; int use_Samorodnitsky = 0; double target_energy = 0.; int statistics_interval = 1; int print_clashes = 0; for (int carg=1; carg>1)^c10^c30; else cube[c][i] |= (i>>1)^c00^c20; } } } if (N==5) { plane_swap(cube, 4, 0, 1); plane_swap(cube, 4, 1, 4); } if (read_stdin) read_cube(cube); print_cube(cube); large **corners; corners = new (large *)[NUpN]; for (large c=0; c0) { cout << "Starting loop...\n"; little **copy, **best; copy = new (little *)[NUpN]; best = new (little *)[NUpN]; for (large c=0; c target_energy); printf("Current cube is\n"); print_cube(cube); printf("bestval.val=%f attained at\n", bestval.val); print_cube(best); } } large *default_order() { large *inv; inv = new large[NpUpN]; large i,j; for (i=0; i0; --j) for (i=0; iinv[i+1]) { t=inv[i]; inv[i]=inv[i+1]; inv[i+1]=t; } large *order; order = new large[NpUpN]; for (i=0; i> x;} while (!(x>='0' && x<'0'+N)); cube[c][i] = x - '0'; } } void print_cube(little **cube) { for (large c=0; c0) { i=0; if (Pi(c,i) != 0) cout << " "; else if (Pi(c, ++i) != 0) cout << " "; else do { cout << "\n"; } while ((++i)0) { i=0; if (Pi(c,i) != 0) cout << " "; else if (Pi(c, ++i) != 0) cout << " "; else do { cout << "\n"; } while ((++i)0) cout << "|"; cout << (int) corners[c][i]; } } cout << "\n"; } void print_tops(large **tops) { large c; little i,j; for (i=0; i0) { j=0; if (Pi(c,j) != 0) cout << " "; else if (Pi(c, ++j) != 0) cout << " "; else do { cout << "\n"; } while ((++j)0) c -= NUp[i];} else {if (Pi3(pert,i)==2) if (ok = Pi(b,i)b = b; cdata[d]->c = c; cdata[d]++; for (little i=0; i= **(high++)) clash=0; if (clash) { currval.val += 1.; ++currval.clashes; if (currval.clashes<=pc) { printf("%d:",d); for (little i=0; i pc) printf("..."); printf("\n"); } return currval; } void box_rotate(little **cube, large c, little a, little b) { little t = cube[c][a]; cube[c][a] = cube[c][b]; cube[c][b] = t; } void plane_swap(little **cube, little ind, little a, little b) { large diff = NUp[ind]*(b-a); for (large c=0; c