#include #include #include #include #define INSET(member,set) ((1<<(member))&(set)) #define INCL(set,member) ((set) |= 1<<(member)) int main() { const int size = 8; /* square size of the board */ struct { int row, col; } pos[size]; /* queen positions */ /* a queen on (row, col) threatens a row, a column, and 2 diagonals; rows and columns are characterized by their number (0..n-1), the diagonals by row-col+n-1 and row+col, (n is a shorthand for the square size of the board) */ int rows = 0, cols = 0; /* bitmaps of [0..n-1] */ int diags1 = 0; /* bitmap of [0..2*(n-1)] used for row-col+n-1 */ int diags2 = 0; /* bitmap of [0..2*(n-1)] used for row+col */ int row = 0; int col; setnextqueen: for (col = 0; col < size; ++col) { if (INSET(row, rows)) continue; if (INSET(col, cols)) continue; if (INSET(row - col + size - 1, diags1)) continue; if (INSET(row + col, diags2)) continue; int child = fork(); if (child == -1) { perror("fork"); exit(255); } if (child == 0) { INCL(rows, row); INCL(cols, col); INCL(diags1, row - col + size - 1); INCL(diags2, row + col); pos[row].row = row; pos[row].col = col; ++row; /* set next queen in next row */ if (row == size) exit(1); /* solution found */ goto setnextqueen; } } /* count the results of all children */ int stat; pid_t child; int nofsolutions = 0; while ((child = wait(&stat)) > 0) { if (!WIFEXITED(stat)) continue; int exitval = WEXITSTATUS(stat); if (exitval == 255) exit(255); nofsolutions += exitval; } exit(nofsolutions); }