/* From Wirth's Algorithms+Data Structures = Programs. */
/* This program is suitable for a code-generation      */
/* benchmark, especially given common sub-expressions  */
/* in array indexing.  See the Programmer's Guide for  */
/* how to get a machine code interlisting.             */

pragma	Title("Eight Queens problem.");

#include <stdio.h>

typedef enum{False,True} Boolean;
typedef int Integer;

#define Asub(I)  A[(I)-1] /* C's restriction that array*/
#define Bsub(I)  B[(I)-2] /* indices start at zero     */
#define Csub(I)  C[(I)+7] /* prompts definition of     */
#define Xsub(I)  X[(I)-1] /* macros to do subscripting.*/
			    /* Pascal equivalents:     */
static Boolean A[ 8 /* 1.. 8 */]; /* A:array[ 1.. 8] of Boolean	*/
static Boolean B[15 /* 2..16 */]; /* B:array[ 2..16] of Boolean	*/
static Boolean C[15 /*-7.. 7 */]; /* C:array[-7.. 7] of Boolean	*/
static Integer X[ 8 /* 1.. 8 */]; /* X:array[ 1.. 8] of Integer	*/

void Try(Integer I, Boolean *Q) {
   Integer J = 0;
   do {
      J++; *Q = False;
      if (Asub(J) && Bsub(I+J) && Csub(I-J)) {
	 Xsub(I) = J;
	 Asub(J) = False; 
	 Bsub(I+J) = False; 
	 Csub(I-J) = False;
	 if (I < 8) {
	    Try(I+1,Q);
	    if (!*Q) {
	       Asub(J) = True; 
	       Bsub(I+J) = True; 
	       Csub(I-J) = True;
	       }
	    }
	 else *Q = True;
	 }
      }
   while (!(*Q || J==8));
   }
pragma Page(1); /* Page eject requested. */
void main () {
   Integer I; Boolean Q;
   printf("%s\n","go");
   for (I =  1; I <=  8; Asub(I++) = True);
   for (I =  2; I <= 16; Bsub(I++) = True);
   for (I = -7; I <=  7; Csub(I++) = True);
   Try(1,&Q);
pragma Skip(3); /* Skip 3 lines. */
   if (Q)
      for (I = 1; I <= 8;) {
	 printf("%4d",Xsub(I++));
	 }
   printf("\n");
   }
