/**************************************************************************/ /* N-Queens Solutions ver3.1 takaken July/2003 */ /**************************************************************************/ #include #include #define MAXSIZE 24 #define MINSIZE 2 int SIZE, SIZEE; int BOARD[MAXSIZE], *BOARDE, *BOARD1, *BOARD2; int MASK, TOPBIT, SIDEMASK, LASTMASK, ENDBIT; int BOUND1, BOUND2; __int64 COUNT8, COUNT4, COUNT2; __int64 TOTAL, UNIQUE; /**********************************************/ /* Display the Board Image */ /**********************************************/ void Display(void) { int y, bit; printf("N= %d\n", SIZE); for (y=0; y>=1) printf("%s ", (BOARD[y] & bit)? "Q": "-"); printf("\n"); } printf("\n"); } /**********************************************/ /* Check Unique Solutions */ /**********************************************/ void Check(void) { int *own, *you, bit, ptn; /* 90-degree rotation */ if (*BOARD2 == 1) { for (ptn=2,own=BOARD+1; own<=BOARDE; own++,ptn<<=1) { bit = 1; for (you=BOARDE; *you!=ptn && *own>=bit; you--) bit <<= 1; if (*own > bit) return; if (*own < bit) break; } if (own > BOARDE) { COUNT2++; //Display(); return; } } /* 180-degree rotation */ if (*BOARDE == ENDBIT) { for (you=BOARDE-1,own=BOARD+1; own<=BOARDE; own++,you--) { bit = 1; for (ptn=TOPBIT; ptn!=*you && *own>=bit; ptn>>=1) bit <<= 1; if (*own > bit) return; if (*own < bit) break; } if (own > BOARDE) { COUNT4++; //Display(); return; } } /* 270-degree rotation */ if (*BOARD1 == TOPBIT) { for (ptn=TOPBIT>>1,own=BOARD+1; own<=BOARDE; own++,ptn>>=1) { bit = 1; for (you=BOARD; *you!=ptn && *own>=bit; you++) bit <<= 1; if (*own > bit) return; if (*own < bit) break; } } COUNT8++; //Display(); } /**********************************************/ /* First queen is inside */ /**********************************************/ void Backtrack2(int y, int left, int down, int right) { int bitmap, bit; bitmap = MASK & ~(left | down | right); if (y == SIZEE) { if (bitmap) { if (!(bitmap & LASTMASK)) { BOARD[y] = bitmap; Check(); } } } else { if (y < BOUND1) { bitmap |= SIDEMASK; bitmap ^= SIDEMASK; } else if (y == BOUND2) { if (!(down & SIDEMASK)) return; if ((down & SIDEMASK) != SIDEMASK) bitmap &= SIDEMASK; } while (bitmap) { bitmap ^= BOARD[y] = bit = -bitmap & bitmap; Backtrack2(y+1, (left | bit)<<1, down | bit, (right | bit)>>1); } } } /**********************************************/ /* First queen is in the corner */ /**********************************************/ void Backtrack1(int y, int left, int down, int right) { int bitmap, bit; bitmap = MASK & ~(left | down | right); if (y == SIZEE) { if (bitmap) { BOARD[y] = bitmap; COUNT8++; //Display(); } } else { if (y < BOUND1) { bitmap |= 2; bitmap ^= 2; } while (bitmap) { bitmap ^= BOARD[y] = bit = -bitmap & bitmap; Backtrack1(y+1, (left | bit)<<1, down | bit, (right | bit)>>1); } } } /**********************************************/ /* Search of N-Queens */ /**********************************************/ void NQueens(void) { int bit; /* Initialize */ COUNT8 = COUNT4 = COUNT2 = 0; SIZEE = SIZE - 1; BOARDE = &BOARD[SIZEE]; TOPBIT = 1 << SIZEE; MASK = (1 << SIZE) - 1; /* 0:000000001 */ /* 1:011111100 */ BOARD[0] = 1; for (BOUND1=2; BOUND1>1); } /* 0:000001110 */ SIDEMASK = LASTMASK = TOPBIT | 1; ENDBIT = TOPBIT >> 1; for (BOUND1=1,BOUND2=SIZE-2; BOUND1>1); LASTMASK |= LASTMASK>>1 | LASTMASK<<1; ENDBIT >>= 1; } /* Unique and Total Solutions */ UNIQUE = COUNT8 + COUNT4 + COUNT2; TOTAL = COUNT8 * 8 + COUNT4 * 4 + COUNT2 * 2; } /**********************************************/ /* Format of Used Time */ /**********************************************/ void TimeFormat(clock_t utime, char *form) { int dd, hh, mm; float ftime, ss; ftime = (float)utime / CLOCKS_PER_SEC; mm = (int)ftime / 60; ss = ftime - (float)(mm * 60); dd = mm / (24 * 60); mm = mm % (24 * 60); hh = mm / 60; mm = mm % 60; if (dd) sprintf(form, "%4d %02d:%02d:%05.2f", dd, hh, mm, ss); else if (hh) sprintf(form, " %2d:%02d:%05.2f", hh, mm, ss); else if (mm) sprintf(form, " %2d:%05.2f", mm, ss); else sprintf(form, " %5.2f", ss); } /**********************************************/ /* N-Queens Solutions MAIN */ /**********************************************/ int main(void) { clock_t starttime; char form[20]; printf("<------ N-Queens Solutions -----> <---- time ---->\n"); printf(" N: Total Unique days hh:mm:ss.--\n"); for (SIZE=MINSIZE; SIZE<=MAXSIZE; SIZE++) { starttime = clock(); NQueens(); TimeFormat(clock() - starttime, form); printf("%2d:%16I64d%16I64d %s\n", SIZE, TOTAL, UNIQUE, form); } return 0; }