You are on page 1of 6

/* The ' N - Queens ' / Eight Queens Problem : Here are my solutions to the N-Queens / 8 queens Problem .

There are three solut ions here . 1. A solution by simple Backtracking / Recursion . (The only array used in this solution is a 1-d array) 2. A solution to the N-Queens / Eight Queens Problem WITHOUT RECURSION . (Using Stacks ) 3. Another recursive function with better ( but vague ) heuristics . The heuristic was completely my own (as far as I know ) , but a bit arbitr ary to some extent . Anyway , I was glad to see that it produced results pretty quickly uptil N = 70 or so . ( That's on a AMD K-6 Machine with 128 MB Ram. ) IMPORTANT , PLEASE READ :::: Regarding the display of solutions : The solutions appear in the following forma t :: Example : SOLN 1 : (1,1) (2,5) (3,8) ..... This means that the queen in the first row must be placed in column 1 , the quee n in the second row must be placed in column 5 , the queen in the third row must be place d in col 8... and so on ....( obviously , there can only be 1 queen for each column or row ) . NOTE : Both solutions 2 & 3 implement the famous method of Niklaus Wirth to use 3 boolean arrays to marks squares already visited . The first solution , though quite economical on memory , is very much inefficient as far as speed is concerned . I put it up because it was the first solution which was completely thought of by me . *** ALL THESE PROGRAMS HAVE BEEN TRIED AND TESTED IN TURBO-CPP *** ----------------------------------------------------------------------------------- */ SOLUTION #1 # include <stdio.h> # include <stdlib.h> # include <time.h> int N; //For N * N ChessBoard int flag; void printArray(int a[]); /* Just to Print the Final Solution */ void getPositions(int a[],int n1,int n2); /* The Recursive Function */ int main() {int *a; int ctr=0; printf("\nTHE N QUEENS PROBLEM "); printf("\nNumber Of Rows(N) For NxN Chessboard."); scanf("%d",&N); a=(int *)(malloc(sizeof(int)*N)); printf("\nAll possible Solutions .. \n"); printf("\nIn Each of the solutions the Coordinates of the N-Queens are given (R ow,Col) ."); printf("\nNote that the Rows and Colums are numbered between 1 - N :\n"); for(ctr=0;ctr<N;ctr++) getPositions(a,0,ctr);

getchar().h> typedef struct { int x.i< colno. scanf("%d". printf("\nIn Each of the solutions the Coordinates of the N-Queens are given ( val) { int ctr1. PROGRAM FOR N QUEENS PROBLEM WITHOUT RECURSION (Using two stacks instead) /*EightQueens Program using two Stacks . SolveProblem(N). for(i=0.a[i]+1). void SolveProblem(int n). scanf("%d". printf("\nNote that the Rows and Colums are numbered between 1 .ctr1<N. for(ctr1=0. } position . getPositions(a1.h> # include <time. void main() {printf("\nENTER THE SIZE OF CHESSBOARD ( N ) FOR NxN CHESSBOARD :").) { /* This Loop Finds Suitable Column Numbers .h> # include <stdlib. a1[colno]=val. counter++.Col) .&N). return. } void printArray(int a[]) { int i. } } /* END OF FIRST PROGRAM*/ ------------------------------------------------------------------------------------2. getchar(). miss1: ctr1++.").%d) ". printf("\nSOLUTION # %d :". static int counter=0.i+1.y. in the NEXT ROW */ for(ctr2=0. } void SolveProblem(int n) . int N=0.&choice). if(colno==N-1) { printArray(a1) .colno+1.").getchar().ctr2<=colno. if(counter%10==0) { printf("\nEnter 0 to exit .counter). }.ctr2++) if(a1[ctr2]==ctr1 || (colno+1-ctr2)*(colno+1-ctr2)==(ctr1-a1[ctr2])*(ctr1-a1[ ctr2])) goto miss1.ctr1). Stacks are implemented using arrays */ # include <stdio.i++) printf("(%d. }. 1 to continue .ctr2.N :\n").choice. } void getPositions(int a1[]. if(choice==0) exit(0).

y=stack2[counter3--]. Position3. d[Position2.counter1<=counter3.x-Position1. Position2. d[Position2.x+1.}. position Position1.counter3=-1. head1[++counter2]=Position3.y.y][1]=0.y+n][2]=0. int *stack2.Position3. int d[100][3]={0}.y=counter1.y][0]=0.counter1>=0.x=0. d[Position1. d[Position2. if(choice==0) exit(0).&choice). }.y+n][2]=1.y=stack2[counter3--].x=counter3. d[Position1.Position2.x<=counter3){ Position2. stack2[++counter3]=Position1.x=counter3.y][0]=0. Position2.counter1>=0. }.counter1--) { Position1.x-Position2. printf("\nSOLUTION # %d:".y+n][2]=0.x=Position1. stack2=(int *)malloc(n*sizeof(int)). d[Position2.counter1+1.x+Position2. position *head1=(position *)malloc(n*n*sizeof(position)).x+Position1.y][1]=0.x-Position2. d[Position2. for(counter1=0.y][1]=1. 0 to end.x+Position2. Position2. } } } .counter).y=counter1. d[Position2.counter1++) printf("(%d. d[Position1. head1[++counter2]=Position1.x+1+counter1][1]==0 && d[n+Position1. Position1.x+1-counter1][2]==0) {Position3. stack2[counter1]+1).{ int counter1.} else{for(counter1=n-1. }. scanf("%d". while(counter3>=0 && Position1.choice. while(counter2>=0){ Position1=head1[counter2--]. if(counter%10==0){printf("\nEnter 1 to Continue . static int counter=0. if(counter3==n-1) { counter++.%d) " .counter1--) if(d[counter1][0]==0 && d[Position1. for(counter1=n-1.y][0]=1.") .counter2=-1.

printf("\nNumber Of Rows/Cols For NxN Chessboard.h> # include <math.motionOrder[0][ctr]). for(ctr=0. void motionorder(const int).ctr--) getPositions(0. scanf("%d"."). void assignSecondOrderPriority(). getchar(). motionorder(n1). printf("\nNote that the Rows and Colums are numbered between 1 . if(choice==0) . static int counter=0.ctr++) secondOrderPriority[ctr]=(long int *)malloc(N*sizeof(lon g int)). secondOrderPriority=(long int **)malloc(N*sizeof(long int *)). int *a1.n1==N).&choice).++counter). a1=(int *)(malloc(sizeof(int)*N)).**secondOrderPriority. assignPriority().h> int N. assignSecondOrderPriority(). priority_array=(long int **)malloc(N*sizeof(long int *)).a[i]+1). int ctr2.i<N. for(i=0. int *a2.ctr<N. N=n1.N :\n"). for(ctr=0. scanf("%d".long int **motionOrder. void assignPriority().Col) .Col) \n"). void getPositions(int .").ctr1.choice. for(ctr=n1-1.3.ctr<N.ctr++) priority_array[ctr]=(long int *)malloc(N*sizeof(long int )). printf("\nSOLN %d :".int). motionOrder=(long int **)malloc(N*sizeof(long int *)). PROGRAM WITH (At Least Some !) HEURISTICS # include <stdio. return 0. getchar()."). 1 to continue.ctr>=0.h> # include <time. a2=(int *)(malloc(sizeof(int)*N)). int main() { int ctr=0. printf("\nAll possible Solutions . } void printArray(int a[]) { int i.h> # include <stdlib. int d[500][3]={0}.ctr++) motionOrder[ctr]=(long int *)malloc(N*sizeof(long int)). if(counter%10==0) {printf("\nEnter 0 to exit. printf("\n N=%d ". printf("\nIn Each of the solutions the Coordinates of the N-Queens are given (R ow. (Row. for(ctr=0. long int **priority_array.n1..ctr<N.&N).i++) printf("%d ". //For N * N ChessBoard void printArray(int a[]).

counter1<N. int leastval.ctr2). d[val][1]=1. d[val][1]=0. d[val+colno][2]=0. for(counter1=0. if(colno==N-1) { printArray(a1). for(counter1=0.counter2.valueToPlace. if(d[ctr2][1]!=1) if(d[ctr2+colno+1][2]!=1) if(d[N+ctr2-colno-1][0]!=1) if(ctr2>=0 && ctr2<N) getPositions(colno+1.exit(0). } } void getPositions(int colno. for(row=0. v2=N-abs(counter1-counter2) . a1[colno]=val. priority_array[counter1][counter2]=2*N+v1+v2-1.ctr1--) {ctr2=(int)motionOrder[colno+1][ctr1].col++) {valueToPlace=0. d[N+val-colno][0]=1.col.counter1<=N/2. d[val+colno][2]=0.counter2++) {if((v1=counter1+counter2+1)>N) v1=2*N-v1. for(counter1=0. if(colno==0) for(ctr1=0.ctr1++) a1[ctr1]=0.row<N.counter1<N.col<N.counter1++) for(counter2=0. d[val][1]=0. callCounter++. } void assignPriority() {long int counter1. } printf("\n"). } d[N+val-colno][0]=0.k=N/2.counter2<=N/2.ctr1<N.row++) for(col=0. } void assignSecondOrderPriority() {static int callCounter=0.counter2<N. d[N+val-colno][0]=0.counter2++) priority_array[counter1][counter2]=0.ctr1>=0. long int row.counter1++) . d[val+colno][2] val) { int ctr1. } else for(ctr1=N-1.counter2.counter1++) for(counter2=0.v1.

while(row-counter1>=0 && col+counter1<N) {valueToPlace+=priority_array[row-counter1][col+counter1]. if(row==0 && col==0) leastval = valueToPlace . counter1++.counter2<N.counter1<N. counter1=0. assignSecondOrderPriority(). counter1=0.counter2<N1.counter1++) for(counter2=0.counter1++) { for(counter2=1. while(row-counter1>=0 && col-counter1>=0) {valueToPlace+=priority_array[row-counter1][col-counter1]. secondOrderPriority[row][col]=valueToPlace-5*priority_array[row][col ]. else if(leastval>valueToPlace) leastval=valueToPlace . while(temp1<secondOrderPriority[counter1][motionOrder[counter1][p-1]] && p-1>=0) {motionOrder[counter1][p]=motionOrder[counter1][p-1]. }.valueToPlace+=priority_array[counter1][col]+priority_array[row][coun ter1].counter2<N1.counter1++) for(counter2=0.counter1<N1. counter1=0. }.counter2++) priority_array[counter1][counter2]=secondOrderPriority[counter1][counter2]-l eastval. } } } . }. p=counter2. for(counter1=0.counter2++) { temp1=secondOrderPriority[counter1][counter2]. } } void motionorder(const int N1) { long int counter1.counter2. for(counter1=0.}. counter1++.p.temp1. }. while(row+counter1<N && col+counter1<N) {valueToPlace+=priority_array[row+counter1][col+counter1].counter1<N1. while(row+counter1<N && col-counter1>=0) {valueToPlace+=priority_array[row+counter1][col-counter1].val1. counter1++. counter1++. } if(callCounter!=8*k-1) { for(counter1=0. val1=motionOrder[counter1][counter2].counter2++) motionOrder[counter1][counter2]=counter2.p=p-1. motionOrder[counter1][p]=val1. counter1=0.