45 lines
2.2 KiB
C
45 lines
2.2 KiB
C
// queens.c Efficient computation of the 8 queens problem
|
|
// Copyleft: http://christophe.lavarenne.free.fr
|
|
|
|
// The 8x8 cells of a chess-board are mapped onto the 64 bits of a long-long.
|
|
// For each possible board with a single queen, two long-long are precomputed:
|
|
// one with a single bit set in the location of the queen, the other with bits
|
|
// cleared if their cell is aligned with the queen, otherwise set as "free".
|
|
// The recursive program starts with all cells free, then each recursion level
|
|
// adds a queen in one of the free cells on the next line, and cleared cells
|
|
// are accumulated by AND-ing together the precomputed long-long of all queens.
|
|
// Every time the 8th recursion level is reached, the resulting solution is
|
|
// printed out in hexadecimal, showing a single bit per byte, i.e. a single
|
|
// queen per chess-board line.
|
|
// It would be nice to eliminate all duplicate symmetrical solutions...
|
|
|
|
#define X0 0x00000000000000FFLL // x=0
|
|
#define Y0 0x0101010101010101LL // y=0
|
|
#define UP 0x8040201008040201LL // y=x
|
|
#define UH 0x80C0E0F0F8FCFEFFLL // y>=x
|
|
#define DN 0x0102040810204081LL // y=7-x
|
|
#define DH 0xFFFEFCF8F0E0C080LL // y>=7-x
|
|
#define Q(x,y) {1LL<<(8*x+y), (1LL<<(8*x+y)) | ~( \
|
|
(X0<<(8*x)) | (Y0<<y) | (y>=x ? (UP<<(y-x))&UH : (UP<<(y+9-x))&~UH) \
|
|
| (y+x==14 ? 0LL : y>=7-x ? (DN<<(y-7+x))&DH : (DN<<(y+x))&~DH) \
|
|
)}
|
|
|
|
struct PF{long long p, f;} pf[64] = { // This is 1Kbytes data.
|
|
Q(0,0), Q(0,1), Q(0,2), Q(0,3), Q(0,4), Q(0,5), Q(0,6), Q(0,7),
|
|
Q(1,0), Q(1,1), Q(1,2), Q(1,3), Q(1,4), Q(1,5), Q(1,6), Q(1,7),
|
|
Q(2,0), Q(2,1), Q(2,2), Q(2,3), Q(2,4), Q(2,5), Q(2,6), Q(2,7),
|
|
Q(3,0), Q(3,1), Q(3,2), Q(3,3), Q(3,4), Q(3,5), Q(3,6), Q(3,7),
|
|
Q(4,0), Q(4,1), Q(4,2), Q(4,3), Q(4,4), Q(4,5), Q(4,6), Q(4,7),
|
|
Q(5,0), Q(5,1), Q(5,2), Q(5,3), Q(5,4), Q(5,5), Q(5,6), Q(5,7),
|
|
Q(6,0), Q(6,1), Q(6,2), Q(6,3), Q(6,4), Q(6,5), Q(6,6), Q(6,7),
|
|
Q(7,0), Q(7,1), Q(7,2), Q(7,3), Q(7,4), Q(7,5), Q(7,6), Q(7,7)
|
|
};
|
|
|
|
#define prettyprint(f) printf("%016llx\n", f) // redefine it at will...
|
|
void queens(long long f, struct PF*pi) { // recursion max 8 levels deep
|
|
struct PF*pj; if(pi==pf+64) prettyprint(f); else // recurse:
|
|
for(pj=pi+8; pi<pj; ++pi) if(f & pi->p) queens(f & pi->f, pj);
|
|
}
|
|
|
|
int main(void) { queens(0xFFFFFFFFFFFFFFFFLL, pf); }
|