Skip to content

Commit

Permalink
N-Queen
Browse files Browse the repository at this point in the history
Signed-off-by: begeekmyfriend <[email protected]>
  • Loading branch information
begeekmyfriend committed Jul 12, 2017
1 parent 3b66491 commit b3f2576
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 73 deletions.
155 changes: 82 additions & 73 deletions 051_n_queens/n_queens.c
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
/*
* Copyright (C) 2015, Leo Ma <[email protected]>
*/

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

static int N;

static inline int conflict(int *stack, int i, int j)
{
int k;
for (k = 0; k < i; k++) {
/* If occupied or in one line */
if (j == stack[k] || abs(i - k) == abs(j - stack[k])) {
return 1;
}
Expand All @@ -20,110 +15,124 @@ static inline int conflict(int *stack, int i, int j)
return 0;
}

static inline void push(int *stack, int i, int j)
static inline void push(int *stack, int row, int col)
{
stack[i] = j;
// printf("push %d %d\n", i, j);
stack[row] = col;
}

static inline int pop(int *stack, int i)
static inline int pop(int *stack, int row)
{
int j = stack[i];
stack[i] = -1;
// printf("pop %d %d\n", i, j);
return j;
int col = stack[row];
stack[row] = -1;
return col;
}

static inline int top(int *stack)
static inline int top(int *stack, int n)
{
int i;
for (i = N - 1; i >= 0; i--) {
if (stack[i] != -1) {
return i;
int row;
for (row = n - 1; row >= 0; row--) {
if (stack[row] != -1) {
return row;
}
}

return 0;
}

void show(int *stack)
static char **solution(int *stack, int n)
{
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (j == stack[i]) {
printf("Q");
} else {
printf(".");
}
int row, col;
char **solution = malloc(n * sizeof(char *));
for (row = 0; row < n; row++) {
char *line = malloc(n + 1);
for (col = 0; col < n; col++) {
line[col] = col == stack[row] ? 'Q' : '.';
}
printf("\n");
line[n] = '\0';
solution[row] = line;
}
return solution;
}

int main(int argc, char **argv)
{
int i, j, sum = 0;
int *stack;

if (argc != 2) {
printf("Usage: ./queen 8\n");
exit(-1);
}

N = atoi(argv[1]);
if (N <= 0) {
exit(0);
/**
** Return an array of arrays of size *returnSize.
** Note: The returned array must be malloced, assume caller calls free().
**/
char*** solveNQueens(int n, int *returnSize) {
int row = 0, col = 0, sum = 0;
char ***solutions = malloc(1000 * sizeof(char **));

int *stack = malloc(n * sizeof(int));
for (row = 0; row < n; row++) {
stack[row] = -1;
}

stack = malloc(N * sizeof(*stack));
if (stack == NULL) {
exit(-1);
}

if (N == 1) {
if (n == 1) {
stack[0] = 0;
show(stack);
printf("This is the %dth solution.\n", ++sum);
exit(0);
}

for (i = 0; i < N; i++) {
stack[i] = -1;
solutions[0] = solution(stack, n);
*returnSize = 1;
return solutions;
}

i = j = 0;
for (; ;) {
for (; i < N; i++) {
while (j < N) {
if (conflict(stack, i, j)) {
while (j == N - 1) {
/* No space for row[i] so backtracking is needed */
if (--i < 0) {
for (; row < n; row++) {
while (col < n) {
if (conflict(stack, row, col)) {
while (col == n - 1) {
/* No other positions in this row and therefore backtracking */
if (--row < 0) {
/* All solution provided */
free(stack);
exit(0);
*returnSize = sum;
return solutions;
}
j = pop(stack, i);
col = pop(stack, row);
}
j++;
col++;
} else {
push(stack, i, j);
push(stack, row, col);
break;
}
}
j = 0;
col = 0;
}

i = top(stack);
if (i == N - 1) {
show(stack);
printf("This is the %dth solution.\n", ++sum);
/* Full stack, a new complete solution */
row = top(stack, n);
if (row == n - 1) {
solutions[sum++] = solution(stack, n);
}

j = pop(stack, i);
j++;
/* Move on to find if there are still other solutions */
col = pop(stack, row);
col++;
}

assert(0);
}

int main(int argc, char **argv)
{
int i, n, row, col, num_of_solution;

if (argc != 2) {
printf("Usage: ./queen 8\n");
exit(-1);
}

n = atoi(argv[1]);
char ***solutions = solveNQueens(n, &num_of_solution);
for (i = 0; i < num_of_solution; i++) {
char **solution = solutions[i];
for (row = 0; row < n; row++) {
char *line = solution[row];
for (col = 0; col < n; col++) {
putchar(line[col]);
}
putchar('\n');
}
printf("The %dth solution.\n", i + 1);
}

return 0;
}
2 changes: 2 additions & 0 deletions 052_n_queens/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
all:
gcc -O2 -o queen n_queens.c
94 changes: 94 additions & 0 deletions 052_n_queens/n_queens.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
static inline int conflict(int *stack, int i, int j)
{
int k;
for (k = 0; k < i; k++) {
/* If occupied or in one line */
if (j == stack[k] || abs(i - k) == abs(j - stack[k])) {
return 1;
}
}
return 0;
}

static inline void push(int *stack, int row, int col)
{
stack[row] = col;
}

static inline int pop(int *stack, int row)
{
int col = stack[row];
stack[row] = -1;
return col;
}

static inline int top(int *stack, int n)
{
int row;
for (row = n - 1; row >= 0; row--) {
if (stack[row] != -1) {
return row;
}
}
return 0;
}

int totalNQueens(int n) {
int row = 0, col = 0, sum = 0, cap = 1;
int *stack = malloc(n * sizeof(int));
for (row = 0; row < n; row++) {
stack[row] = -1;
}

if (n == 1) {
return 1;
}

for (; ;) {
for (; row < n; row++) {
while (col < n) {
if (conflict(stack, row, col)) {
while (col == n - 1) {
/* No other positions in this row and therefore backtracking */
if (--row < 0) {
/* All solution provided */
free(stack);
return sum;
}
col = pop(stack, row);
}
col++;
} else {
push(stack, row, col);
break;
}
}
col = 0;
}

/* Full stack, a new complete solution */
row = top(stack, n);
if (row == n - 1) {
sum++;
}

/* Move on to find if there are still other solutions */
col = pop(stack, row);
col++;
}
}

int main(int argc, char **argv)
{
if (argc != 2) {
printf("Usage: ./queen 8\n");
exit(-1);
}

int n = atoi(argv[1]);
printf("Total %d solution for %d queens.\n", totalNQueens(n), n);
return 0;
}

0 comments on commit b3f2576

Please sign in to comment.