[llvm-commits] CVS: llvm-test/SingleSource/Benchmarks/McGill/Makefile README.txt chomp.c exptree.c misr.c queens.c

Chris Lattner lattner at cs.uiuc.edu
Tue Oct 5 13:58:50 PDT 2004



Changes in directory llvm-test/SingleSource/Benchmarks/McGill:

Makefile added (r1.1)
README.txt added (r1.1)
chomp.c added (r1.1)
exptree.c added (r1.1)
misr.c added (r1.1)
queens.c added (r1.1)
---
Log message:

New benchmarks


---
Diffs of the changes:  (+1466 -0)

Index: llvm-test/SingleSource/Benchmarks/McGill/Makefile
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/Makefile:1.1
*** /dev/null	Tue Oct  5 15:58:47 2004
--- llvm-test/SingleSource/Benchmarks/McGill/Makefile	Tue Oct  5 15:58:37 2004
***************
*** 0 ****
--- 1,5 ----
+ LEVEL = ../../..
+ LDFLAGS += -lm 
+ FP_TOLERANCE := 0.001
+ 
+ include $(LEVEL)/SingleSource/Makefile.singlesrc


Index: llvm-test/SingleSource/Benchmarks/McGill/README.txt
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/README.txt:1.1
*** /dev/null	Tue Oct  5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/README.txt	Tue Oct  5 15:58:37 2004
***************
*** 0 ****
--- 1,3 ----
+ These benchmarks were downloaded from:
+ http://www.prolangs.rutgers.edu/public.html
+ 


Index: llvm-test/SingleSource/Benchmarks/McGill/chomp.c
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/chomp.c:1.1
*** /dev/null	Tue Oct  5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/chomp.c	Tue Oct  5 15:58:37 2004
***************
*** 0 ****
--- 1,424 ----
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
+ #define NDATA (int *)malloc(ncol * sizeof(int))
+ #define NLIST (struct _list *)malloc(sizeof(struct _list))
+ #define NPLAY (struct _play *)malloc(sizeof(struct _play))
+ 
+ struct _list
+ {
+   int *data;
+   struct _list *next;
+ } *wanted;
+ 
+ struct _play
+ {
+   int value;
+   int *state;
+   struct _list *first;
+   struct _play *next;
+ } *game_tree;
+ 
+ int nrow,ncol;      /* global so as to avoid passing them all over the place */
+ 
+ int *copy_data(data) /* creates a duplicate of a given -data list */
+ int *data;
+ {
+   int *new = NDATA;
+   int counter = ncol;
+   while (counter --)
+       new[counter] = data[counter];
+   return new;
+ }
+ 
+ int next_data(int *data)  /* gives the next logical setup to the one passed */
+                           /* new setup replaces the old. Returns 0 if no valid */
+ {                         /* setup exists after the one passed */
+   int counter = 0;
+   int valid = 0;     /* default to none */
+   while ((counter != ncol) && (! valid)) /* until its done */
+     {
+       if (data[counter] == nrow) /* if we hit a border */
+         {
+ 	  data[counter] = 0;     /* reset it to zero     */
+ 	  counter ++;      /* and take next column */
+ 	}
+        else
+         {
+ 	  data[counter] ++;      /* otherwise, just increment row number */
+ 	  valid = 1;                /* and set valid to true. */
+ 	}
+     }
+   return valid;                     /* return whether or not */
+ }                                   /* a next could be found */
+ 
+ void melt_data(int *data1,int *data2) /* melts 2 _data's into the first one. */
+ {
+   int counter = ncol;
+   while (counter --)     /* do every column */
+     {
+       if (data1[counter] > data2[counter]) /* take the lowest one */
+           data1[counter] = data2[counter]; /* and put in first _data */
+     }
+ }
+ 
+ int equal_data(int *data1,int *data2) /* check if both _data's are equal */
+ {
+   int counter = ncol;
+   while ((counter --) && (data1[counter] == data2[counter]));
+   return (counter < 0);
+ }
+ 
+ int valid_data(int *data) /* checks if the play could ever be achieved. */
+ {
+   int low;      /* var to hold the current height */
+   int counter = 0;
+   low = nrow;   /* default to top of board */
+   while (counter != ncol) /* for every column */
+     {
+       if (data[counter] > low) break;  /* if you get something higher */
+       low = data[counter];             /* set this as current height */
+       counter ++;
+     }
+   return (counter == ncol);
+ }
+ 
+ void dump_list(struct _list *list) /* same for a _list structure */
+ {
+   if (list != NULL)
+     {
+       dump_list(list -> next); /* dump the rest of it */
+       free(list -> data); /* and its _data structure */
+       free(list);
+     }
+ }
+ 
+ void dump_play(play) /* and for the entire game tree */
+ struct _play *play;
+ {
+   if (play != NULL)
+     {
+       dump_play(play -> next);  /* dump the rest of the _play */
+       dump_list(play -> first); /* its _list */
+       free(play -> state); /* and its _data */
+       free(play);
+     }
+ }
+ 
+ int get_value(int *data) /* get the value (0 or 1) for a specific _data */
+ {
+   struct _play *search;
+   search = game_tree; /* start at the begginig */
+   while (! equal_data(search -> state,data)) /* until you find a match */
+       search = search -> next; /* take next element */
+   return search -> value; /* return its value */
+ }
+ 
+ void show_data(int *data) /* little display routine to give off results */
+ {
+   int counter = 0;
+   while (counter != ncol)
+     {
+       printf("%d",data[counter ++]);
+       if (counter != ncol) putchar(',');
+     }
+ }
+ 
+ void show_move(int *data) /* puts in the "(" and ")" for show_data() */
+ {
+   putchar('(');
+   show_data(data);
+   printf(")\n");
+ }
+ 
+ void show_list(struct _list *list) /* show the entire list of moves */
+ {
+   while (list != NULL)
+     {
+       show_move(list -> data);
+       list = list -> next;
+     }
+ }
+ 
+ void show_play(struct _play *play) /* to diplay the whole tree */
+ {
+   while (play != NULL)
+     {
+       printf("For state :\n");
+       show_data(play -> state);
+       printf("  value = %d\n",play -> value);
+       printf("We get, in order :\n");
+       show_list(play -> first);
+       play = play -> next;
+     }
+ }
+ 
+ int in_wanted(int *data) /* checks if the current _data is in the wanted list */
+ {
+   struct _list *current;
+   current = wanted; /* start at the begginig */
+   while (current != NULL) /* unitl the last one */
+     {
+       if (equal_data(current -> data,data)) break; /* break if found */
+       current = current -> next; /* take next element */
+     }
+   if (current == NULL) return 0; /* if at the end, not found */
+   return 1;
+ }
+ 
+ int *make_data(int row,int col) /* creates a new _data with the correct */
+                                 /* contents for the specified row & col */
+ {
+   int count;
+   int *new = NDATA;
+   for (count = 0;count != col;count ++) /* creates col-1 cells with nrow */
+       new[count] = nrow;
+   for (;count != ncol;count ++) /* and the rest with row as value */
+       new[count] = row;
+   return new;         /* and return pointer to first element */
+ }
+ 
+ struct _list *make_list(int *data,int *value,int *all) /* create the whole _list of moves */
+                                                           /* for the _data structure data */
+ {
+   int row,col;
+   int *temp;
+   struct _list *head,*current;
+   *value = 1; /* set to not good to give */
+   head = NLIST; /* create dummy header */
+   head -> next = NULL; /* set NULL as next element */
+   current = head;      /* start from here */
+   for (row = 0;row != nrow;row ++) /* for every row */
+     {
+       for (col = 0;col != ncol;col ++) /* for every column */
+         {
+ 	  temp = make_data(row,col); /* create _data for this play */
+ 	  melt_data(temp,data);      /* melt it with the current one */
+ 	  if (! equal_data(temp,data)) /* if they are different, it good */
+ 	    {
+ 	      current -> next = NLIST; /* create new element in list */
+ 	      current -> next -> data = copy_data(temp); /* copy data, and place in list */
+ 	      current -> next -> next = NULL; /* NULL the next element */
+ 	      current = current -> next; /* advance pointer */
+ 	      if (*value == 1) /* if still not found a good one */
+ 	          *value = get_value(temp); /* look at this value */
+ 	      if ((! *all) && (*value == 0))
+ 	        {  /* if we found it, and all is not set */
+ 		  col = ncol - 1; /* do what it take sto break out now */
+ 		  row = nrow - 1;
+ 	          if (in_wanted(temp)) /* if in the wanted list */
+ 		      *all = 2; /* flag it */
+ 		}
+ 	    }
+ 	   else /* if its not a valid move */
+ 	    {
+ 	      if (col == 0) row = nrow - 1; /* break out if at first column */
+ 	      col = ncol - 1;               /* but make sure you break out */
+ 	    }                               /* of the col for-loop anyway */
+ 	  free(temp); /* dump this unneeded space */
+ 	}
+     }
+   current = head -> next; /* skip first element */
+   free(head); /* dump it */
+   if (current != NULL) *value = 1 - *value; /* invert value if its */
+   return current;                           /* not the empty board */
+ }
+ 
+ struct _play *make_play(int all) /* make up the entire tree-like stuff */
+ {
+   int val;
+   int *temp;
+   struct _play *head,*current;
+   head = NPLAY; /* dummy header again */
+   current = head; /* start here */
+   game_tree = NULL; /* no elements yet */
+   temp = make_data(0,0); /* new data, for empty board */
+   temp[0] --;   /* set it up at (-1,xx) so that next_data() returns (0,xx) */
+   while (next_data(temp)) /* take next one, and break if none */
+     {
+       if (valid_data(temp)) /* if board position is possible */
+         {
+ 	  current -> next = NPLAY; /* create a new _play cell */
+ 	  if (game_tree == NULL) game_tree = current -> next;
+ 	      /* set up game_tree if it was previously NULL */
+ 	  current -> next -> state = copy_data(temp); /* make a copy of temp */
+ 	  current -> next -> first = make_list(temp,&val,&all);
+ 	      /* make up its whole list of possible moves */
+ 	  current -> next -> value = val; /* place its value */
+ 	  current -> next -> next = NULL; /* no next element */
+ 	  current = current -> next;      /* advance pointer */
+ 	  if (all == 2)                   /* if found flag is on */
+ 	    {
+ 	      free(temp);            /* dump current temp */
+ 	      temp = make_data(nrow,ncol); /* and create one that will break */
+ 	    }
+ 	}
+     }
+   current = head -> next; /* skip first element */
+   free(head);             /* dump it */
+   return current;         /* and return pointer to start of list */
+ }
+ 
+ void make_wanted(int *data) /* makes up the list of positions from the full board */
+ {
+          /* everything here is almost like in the previous function. */
+ 	 /* The reason its here, is that it does not do as much as   */
+ 	 /* the one before, and thus goes faster. Also, it saves the */
+ 	 /* results directly in wanted, which is a global variable.  */
+ 
+   int row,col;
+   int *temp;
+   struct _list *head,*current;
+   head = NLIST;
+   head -> next = NULL;
+   current = head;
+   for (row = 0;row != nrow;row ++)
+     {
+       for (col = 0;col != ncol;col ++)
+         {
+ 	  temp = make_data(row,col);
+ 	  melt_data(temp,data);
+ 	  if (! equal_data(temp,data))
+ 	    {
+ 	      current -> next = NLIST;
+ 	      current -> next -> data = copy_data(temp);
+ 	      current -> next -> next = NULL;
+ 	      current = current -> next;
+ 	    }
+ 	   else
+ 	    {
+ 	      if (col == 0) row = nrow - 1;
+ 	      col = ncol - 1;
+ 	    }
+ 	  free(temp);
+ 	}
+     }
+   current = head -> next;
+   free(head);
+   wanted = current;
+ }
+ 
+ int *get_good_move(struct _list *list) /* gets the first good move from a _list */
+ {
+   if (list == NULL) return NULL; /* if list is NULL, say so */
+       /* until end-of-list or a good one is found */
+       /* a good move is one that gives off a zero value */
+   while ((list -> next != NULL) && (get_value(list -> data)))
+       list = list -> next;
+   return copy_data(list -> data); /* return the value */
+ }
+ 
+ int *get_winning_move(struct _play *play) /* just scans for the first good move */
+                                           /* in the last _list of a _play. This */
+ {                                         /* is the full board */
+   int *temp;
+   while (play -> next != NULL) play = play -> next; /* go to end of _play */
+   temp = get_good_move(play -> first); /* get good move */
+   return temp;                         /* return it */
+ }
+ 
+ struct _list *where(int *data,struct _play *play)
+ {
+   while (! equal_data(play -> state,data)) /* search for given _data */
+       play = play -> next;
+   return play -> first;  /* return the pointer */
+ }
+ 
+ void get_real_move(int *data1,int *data2,int *row,int *col) /* returns row & col of the move */
+                                                            /* which created data1 from data2 */
+ {
+   *col = 0;
+   while (data1[*col] == data2[*col]) /* until there is a change */
+       (*col) ++;             /* and increment col number */
+   *row = data1[*col];  /* row is given by the content of the structure */
+ }
+ 
+ void main(void)
+ {
+   int row,col,maxrow,player;
+   int *win,*current,*temp;
+   struct _play *tree,*look;
+     /* allow user to select mode */
+   printf("Mode : 1 -> multiple first moves\n");
+   printf("       2 -> report game\n");
+   printf("       3 -> good positions\n");
+   printf(" Selection : ");
+ #if 0
+   scanf("%d",&row); /* put it in row for now */
+ #else
+   row = 2;
+ #endif
+   switch (row)
+     {
+       case 1:
+         printf("Enter number of Columns       : ");
+         scanf("%d",&ncol);
+         printf("Enter Initial number of Rows : ");
+         scanf("%d",&nrow);
+         printf("Enter Maximum number of Rows : ");
+         scanf("%d",&maxrow);
+         for (;nrow <= maxrow;nrow ++)
+           {
+             make_wanted(make_data(nrow,ncol)); /* created wanted list */
+             tree = make_play(0);               /* create tree */
+             win = get_winning_move(tree);      /* get the winning move */
+ 	        /* get the coordinates of this move */
+             get_real_move(win,make_data(nrow,ncol),&row,&col);
+ 	        /* print it out nicely */
+             printf("The winning initial move for %d x %d CHOMP is (%d,%d)\n",nrow,ncol,row,col);
+             dump_play(tree);  /* dump for memory management */
+             dump_list(wanted);
+           }
+         break;
+       case 2:
+         printf("Enter number of Columns : ");
+ #if 0
+ 	scanf("%d",&ncol);
+ #else
+ 	ncol = 7;
+ #endif
+ 	printf("Enter number of Rows    : ");
+ #if 0
+ 	scanf("%d",&nrow);
+ #else
+ 	nrow = 8;
+ #endif
+ 	tree = make_play(1); /* create entire tree structure, not just the */
+ 	player = 0;          /* needed part for first move */
+ 	current = make_data(nrow,ncol); /* start play at full board */
+ 	while (current != NULL)
+ 	  {
+ 	    temp = get_good_move(where(current,tree)); /* get best move */
+ 	    if (temp != NULL)  /* temp = NULL when the poison pill is taken */
+ 	      {
+ 	        get_real_move(temp,current,&row,&col); /* calculate coordinates */
+ 		    /* print it out nicely */
+ 	        printf("player %d plays at (%d,%d)\n",player,row,col);
+ 	        player = 1 - player; /* next player to do the same */
+ 	        free(current);  /* dump for memory management */
+ 	      }
+ 	    current = temp; /* update board */
+ 	  }
+ 	dump_play(tree); /* dump unneeded tree */
+ 	printf("player %d loses\n",1 - player); /* display winning player */
+ 	break;
+       case 3:
+         printf("Enter number of Columns : ");
+ 	scanf("%d",&ncol);
+ 	printf("Enter number of Rows    : ");
+ 	scanf("%d",&nrow);
+ 	printf("ATTENTION : representation is as in a _data structure\n");
+ 	tree = make_play(1); /* create tree */
+ 	look = tree;         /* start here */
+ 	while (look != NULL)
+ 	  {
+ 	    if (look -> value == 0) /* show all positions bad for player 2 */
+ 	        show_move(look -> state); /* i.e. bad positions to be in */
+ 	    look = look -> next;          /* with zero value */
+ 	  }
+ 	dump_play(tree); /* dump for memory management */
+         break;
+     }
+ }
+ 
+ /*****************************************************************************/


Index: llvm-test/SingleSource/Benchmarks/McGill/exptree.c
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/exptree.c:1.1
*** /dev/null	Tue Oct  5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/exptree.c	Tue Oct  5 15:58:37 2004
***************
*** 0 ****
--- 1,388 ----
+ /***************************************************************************
+ 
+ PART 1: PROGRAM
+ 
+     Pierre Ouellet ID 9009791
+ 
+     The problem solved by this program is stated as follows:
+ 
+     Given a set S of k nonzero natural numbers, labeled n1..nk,
+     a "total" t, which is also a nonzero natural number, find
+     an expression tree, whose leaves are taken from S, and whose
+     interior nodes are each labeled one of {+, -, *, /}, and that
+     evaluates to t. There is the additional restriction that any
+     subtree must evaluate to a natural number greater than 0.
+     Division is permitted only if the value of the left child
+     is exactly divisible by the value of the right child. Also,
+     numbers in S may not be used more times than they appear,
+     e.g. if S = { 2, 3, 3 }, "3" may be used at most twice.
+ 
+     The program uses a brute-force search, more precisely an
+     iterative deepening depth-first search. The search can be
+     viewed as an attempt to build the tree bottom-up: whenever
+     the value t is not present, we try to obtain it by "combining"
+     two available values, which are taken from the "work list",
+     which consists of those elements of S not yet used and the values
+     obtained by previous combinations. This is the equivalent of
+     creating a new root and making the two operands its children.
+ 
+     The work list is an array of integers, originally containing
+     the elements of S. When elements are combined, they're marked
+     used and the result of combining them (the result of evaluating
+     the new root) is added at the end of the list.
+ 
+     The combinations are saved in an array of Comb, to be printed out
+     when a solution is found.
+ 
+ ***************************************************************************/
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ 
+ #define NOOP		0
+ #define ADD		1
+ #define SUB		2
+ #define MUL		3
+ #define DIV		4
+ 
+ typedef struct
+ {
+     int operand1, operand2;
+     int operation;
+ 
+ } Comb;
+ 
+ /* Global variables are used to save time during the search */
+ 
+ static int goal;	    /* the value of t explained above */
+ static int listLength;      /* |S| */
+ static int *workList;	    
+ static Comb *combList;
+ static Comb *solution;
+ static int best = 0;	    /* value of best solution found yet */
+ static int dmax;	    /* maximal depth of search */
+ static int stopSearch;	    /* flag so we stop at first solution */
+ static int bestDepth = 0;   /* depth of best solution; used if no exact
+ 			       solution is found */
+ static int nbNodes;	    /* statistics: number of nodes examined
+ 			       (number of calls to recSearch) */
+ 
+ /************************* INITIALIZATION STUFF *************************/
+ 
+ int *newWorkList( int length )
+ 
+ /*  Create a "work list", which is an array of integers with length
+     elements
+ */
+ 
+ {
+     int *newList = (int *) calloc( length, sizeof( int ) );
+ 
+     if( newList ) return newList;
+ 
+     else
+     {
+ 	fprintf( stderr, "Out of memory for work list\n" );
+ 	exit( 1 );
+     }
+ }
+ 
+ Comb *newCombList( int length )
+ 
+ /*  Create a "combination list", which is to be used all the way through
+     the search. It contains the combinations attempted so far in the search.
+ */
+ 
+ {
+     Comb *newList = (Comb *) calloc( length, sizeof( Comb ) );
+ 
+     if( newList ) return newList;
+ 
+     else
+     {
+ 	fprintf( stderr, "Out of memory for combination list\n" );
+ 	exit( 1 );
+     }
+ }
+ 
+ void initWorkList( int *workList, int *givenList, int length )
+ 
+ {
+     int i;
+ 
+     for( i = 0; i < length; i++ )
+ 	workList[i] = givenList[i];
+ }
+ 
+ void initCombList( Comb *combList, int length )
+ {
+     int i;
+ 
+     for( i = 0; i < length; i++ )
+ 	combList[i].operation = NOOP;
+ }
+ 
+ /************************* AUXILIARY FUNCTIONS *************************/
+ 
+ void saveSolution( Comb *sol, Comb *combList, int length )
+ 
+ /*  Copy a sequence of combinations.
+ */
+ 
+ {
+     int i;
+ 
+     for( i = 0; i < length; i++ )
+     {
+ 	sol[i].operand1 = combList[i].operand1;
+ 	sol[i].operand2 = combList[i].operand2;
+ 	sol[i].operation = combList[i].operation;
+     }
+ 
+     sol[length].operation = NOOP; /* End marker */
+ 
+ }
+ 
+ int calculate( Comb *comb )
+ 
+ /*  Compute the value generated by a combination.
+ */
+ 
+ {
+     switch( comb->operation )
+     {
+ 	case ADD: return comb->operand1 + comb->operand2;
+ 	case SUB: return comb->operand1 - comb->operand2;
+ 	case MUL: return comb->operand1 * comb->operand2;
+ 	case DIV: return comb->operand1 / comb->operand2;
+ 
+ 	default: return 0;
+     }
+ }
+ 
+ /************************* OUTPUT STUFF *************************/
+ 
+ void printSolution( Comb *combList, int length )
+ {
+     int i;
+ 
+     for( i = 0; i < length; i++ )
+     {
+ 	printf( "%d", combList[i].operand1 );
+ 
+ 	switch( combList[i].operation )
+ 	{
+ 	    case NOOP: printf( " " ); break;
+ 	    case ADD: printf( "+" ); break;
+ 	    case SUB: printf( "-" ); break;
+ 	    case MUL: printf( "*" ); break;
+ 	    case DIV: printf( ":" ); break;
+ 
+ 	    default: printf( " d%d ", combList[i].operation );
+ 	}
+ 
+ 	printf( "%d=%d", combList[i].operand2, calculate( &combList[i] ) );
+ 
+ 	if( i < length - 1 ) printf( "; " ); else printf( ".\n" );
+     }
+ 
+     printf( "\n" );
+ }
+ 
+ void printList( int *list, int length, int mask )
+ {
+     int i;
+ 
+     for( i = 0; i < length; i++ )
+     {
+ 	if( ( 1 << i ) & mask ) continue;
+ 
+ 	printf( "%d ", list[i] );
+     }
+ 
+     printf( "\n" );
+ }
+ 
+ /************************* ACTUAL SEARCH STUFF *************************/
+ 
+ void recSearch( int searchDepth, int usedMask )
+ 
+ /*  searchDepth:    current depth within the search.
+     usedMask:	    used to tell which elements of the work list
+ 		    have been used.
+ */
+ 
+ {
+     int currOp;	  /* current operation under consideration */
+     int newMask;  /* or'ed with old mask to mark used numbers from work list */
+     int operand1; /* offset of operand 1 of combination within work list */
+     int operand2; /* offset of operand 2 of combination within work list */
+ 
+     if( stopSearch ) return; /* unroll recursion when solution is found */
+ 
+     nbNodes++; /* Statistics */
+ 
+     if( searchDepth == dmax )
+     {
+ 	/* check whether last number generated is nearer to t than best */
+ 	if( abs( workList[listLength + searchDepth - 1] - goal )
+ 	   < abs( best - goal ) )
+ 	{
+ 	    /* if so, save solution */
+ 	    best = workList[listLength + searchDepth - 1];
+ 	    bestDepth = searchDepth;
+ 	    saveSolution( solution, combList, searchDepth );
+ 
+ 	    if( best == goal )
+ 	    {
+ 		printSolution( combList, searchDepth );
+ 		stopSearch = 1;
+ 	    }
+ 	}
+     }
+ 
+     else
+     {
+ 	int working1, working2; /* hold values of numbers considered
+ 				   for combination */
+ 	int temp;		/* for swapping */
+ 
+ 	/* iterate over all four operators {+, -, *, /} */
+ 	for( currOp = ADD; currOp <= DIV; currOp++ )
+ 	{
+ 	    for( operand1 = 0; operand1 < listLength + searchDepth;
+ 		operand1++ )
+ 	    {
+ 		/* do not use already used numbers */
+ 		if( ( 1 << operand1 ) & usedMask ) continue;
+ 
+ 		for( operand2 = 0; operand2 < operand1; operand2++ )
+ 		{
+ 		    if( ( 1 << operand2 ) & usedMask ) continue;
+ 
+ 		    working1 = workList[operand1];
+ 		    working2 = workList[operand2];
+ 
+ 		    /* x * 1 = 1 * x = x; x / 1 = x */
+ 		    if( ( currOp == MUL || currOp == DIV ) &&
+ 		        ( working1 == 1 || working2 == 1 ) ) continue;
+ 
+ 		    /* could arise from combination a - a for some a */
+ 		    if( working1 == 0 || working2 == 0 ) continue;
+ 
+ 		    /* make dure operand2 divides operand1 */
+ 		    if( currOp == DIV &&
+ 		       ( working1 % working2 ) ) continue;
+ 
+ 		    /* make sure operand1 >= operand2 for subtraction and
+ 		       division */
+ 		    if( ( currOp == DIV || currOp == SUB ) &&
+ 		        ( working1 < working2 ) )
+ 		    {
+ 			temp = working1;
+ 			working1 = working2;
+ 			working2 = temp;
+ 		    }
+ 
+ 		    /* mark operands used */
+ 		    newMask = usedMask |
+ 			     ( 1 << operand1 ) |
+ 			     ( 1 << operand2 );
+ 
+ 		    /* save current combination */
+ 		    combList[searchDepth].operand1 =
+ 			working1;
+ 		    combList[searchDepth].operand2 =
+ 			working2;
+ 		    combList[searchDepth].operation = currOp;
+ 
+ 		    workList[listLength + searchDepth] =
+ 			calculate( &combList[searchDepth] );
+ 
+ 		    /* search deeper */
+ 		    recSearch( searchDepth + 1, newMask );
+ 		}
+ 	    }
+ 	}
+     }
+ }
+ 
+ void doSearch(void)
+ 
+ /*  Preliminary search. Takes care of the special case where |S| = 1
+     and the only element of S is t.
+ */
+ {
+     int i;
+ 
+     for( i = 0; i < listLength; i++ )
+ 	if( abs( workList[i] - goal ) < abs( best - goal ) )
+ 	{
+ 	    best = workList[i];
+ 	}
+ 
+     if( best == goal )
+     {
+         printf( ".\n" );
+ 	return;
+     }
+ 
+     for( dmax = 1; dmax < listLength; dmax++ )
+     {
+ 	recSearch( 0, 0 );
+ 
+ 	if( stopSearch ) break;
+     }
+ 
+     /* If no exact solution was found */
+     if( stopSearch == 0 )
+ 	printSolution( solution, bestDepth );
+ }
+ 
+ int getInput(void)
+ {
+     int nums[16];
+     int i = 0;
+     int c;
+     nums[0] = 13;
+     nums[1] = 32;
+     nums[2] = 14;
+     nums[3] = 1412;
+ 
+     while( ( c = getchar() ) != '\n' && c != EOF )
+     {
+ 	ungetc( c, stdin );
+ 	fscanf( stdin, "%d", &nums[i] );
+ 	i++;
+     }
+ 
+     if( i == 0 ) i = 4;
+ 
+     listLength = i - 1;
+     goal = nums[listLength];
+     
+     workList = newWorkList( 2 * listLength );
+     combList = newCombList( listLength );
+     solution = newCombList( listLength );
+ 
+     initWorkList( workList, nums, listLength );
+     initCombList( combList, listLength );
+     initCombList( solution, listLength );
+ 
+     return( listLength );
+ }
+ 
+ void search(void)
+ {
+     /* set up global variables for search */
+     stopSearch = 0;
+     nbNodes = 0;
+ 
+     doSearch();
+ }
+ 
+ void main( int argc, char *argv[] )
+ {
+     if( getInput() )
+ 	search();
+ }


Index: llvm-test/SingleSource/Benchmarks/McGill/misr.c
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/misr.c:1.1
*** /dev/null	Tue Oct  5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/misr.c	Tue Oct  5 15:58:37 2004
***************
*** 0 ****
--- 1,280 ----
+ /* the name was converted to pgm5.c */
+ /*******************************************************
+ 
+ program:	MISR.C
+ 
+ 
+ This program creates two MISR's one which contains the 
+ true outputs and the other in which the outputs are 
+ not currupted with the probability given in the input. 
+ The values of the MISR's are compared to see if the
+ introduced errors have cancelled themselves.
+ 
+ The usage  is : MISR fileout reg_len #_vectors prob 
+ #_times [structure] [seed] [seed] [seed].
+ fileout has been nullified in this case to fit with
+     the description of the project.
+ reg_len is the length of the MISR's in considerstion.
+ #_vectors is the number of vectors to input to the 
+     MISR's before checking to see of they are 
+     identical. If '0', assume large value (infinite).
+ prob described above.
+ #_times is the number of times that the MISR's are 
+     initialized and the experiment done before the
+     # of times outputs same/ # of times it is run
+     (#_times) is calculated.
+ [structure] gives the feedback structure of the MISR's.
+     if it is omitted, the  situition where the end   
+     feeds back to the beginning is used.
+ [seed]* is the seed to be used to initialize the random
+     generator.
+ *******************************************************/
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <mp.h>
+ 
+ #define INF 10000
+ #define MAX_REG_LN 100
+ #define BIN_MASK 1
+ #define TRUE 1
+ #define FALSE 0
+ 
+ int reg_len;
+ 
+ typedef struct cells {
+         int f_free;
+ 	int faulty;
+         struct cells *next;
+         }misr_type;
+ 
+ /* Prototypes */
+ 
+ int simulate(int iterations, misr_type *present, double prob, char *structure);
+ void init(misr_type *present);
+ void kill_list(misr_type *present);
+ void create_link_list(misr_type *cell_array);
+ 
+ /* Main Program */
+ 
+ void main(int argc,char *argv[])
+ {
+         misr_type cell_array;
+ 	int num_vect, num_times, num_true, i;
+ 	double prob;
+ 	char structure[MAX_REG_LN];
+ 	unsigned short seed[3];
+ 
+ /* Check usage */
+ 	if (0 && argc < 6)
+ 	{
+ 		printf("Usage: MISR fileout reg_len #_vectors prob #_times [structure] [seed] [seed] [seed]\n");
+ 		return;
+ 	}
+ 
+ /* input and translate arguments */
+ 	/*sscanf(argv[2], "%lu", &reg_len);
+ 	sscanf(argv[3], "%lu", &num_vect);
+ 	sscanf(argv[4], "%le", &prob);
+ 	sscanf(argv[5], "%lu", &num_times);*/
+ 
+         reg_len = num_vect = 10;
+         prob = .25;
+         num_times = 100000;
+ 
+ 
+ 	if (argc > 6) strcpy(structure, argv[6]);
+ 	else {
+ 		for (i=1; i<reg_len; i++)
+ 			structure[i] = '0';
+ 		structure[0] = '1';
+ 		structure[reg_len] = NULL;
+ 	}
+         if (argc > 7) sscanf(argv[7], "%hu", &seed[0]); else seed[0] = 1;
+         if (argc > 8) sscanf(argv[8], "%hu", &seed[1]); else seed[1] = 0;
+         if (argc > 9) sscanf(argv[9], "%hu", &seed[2]); else seed[2] = 0;
+ 
+ 
+ /* Check validity of input */
+ 	if (reg_len > MAX_REG_LN)
+ 	{
+ 		printf("Register too long; Max. = %d\n", MAX_REG_LN);
+ 		return;
+ 	}
+ 	if ((prob > 1) || (prob < 0))
+ 	{
+ 		printf("Prob. out of range 0=<Prob>=1\n");
+ 		return;
+ 	}
+ 	if (strlen(structure) != reg_len)
+ 	{
+ 		printf("Structure does not match Register length:\n");
+ 		return;
+ 	}
+ 
+ 
+ /*initialize random f'n generator */
+         seed48(seed);
+ 
+ 
+ /* create MISRs of reg_len length */
+ 	create_link_list(&cell_array);
+ 
+ /* simulate both circuits */
+ 	num_true = 0; 
+ 	if (num_vect != 0)
+ 	{
+ 		for (i=0; i<num_times; i++)
+ 		{
+ 			init(&cell_array);
+ 			num_true += simulate(num_vect, &cell_array, prob, structure);
+ 		}
+ 	}
+ 	else  /* ie. infinite case */
+ 	{
+ 		init(&cell_array); 
+ 		simulate(INF, &cell_array, prob, structure);
+ 		for(i=0; i<num_times; i++)
+ 		{
+ 			num_true += simulate(1, &cell_array, prob, structure);
+ 		}
+ 	}
+ 
+ 
+ /* output results */
+ 	printf("reg_len	#_vect	prob      #_tms	struct	seed1	seed2	seed3	Prob same output\n ");
+ 
+ 	printf("%d	%d	%.3e %d	%s	%d	%d	%d	%.8e\n", reg_len, num_vect, prob, num_times, structure, seed[0], seed[1], seed[2],(double)(num_times - num_true)/(double)num_times);
+ 	//kill_list(&cell_array);
+ }
+ 
+ /*************************************************************
+ create and initialize the MISR's which is a linked list of 
+ misr_type.
+ *************************************************************/
+ void create_link_list(misr_type *cell_array)
+ {
+ 	int i;
+ 	misr_type *temp, *present;
+ 
+         memset(cell_array, 0, sizeof(*cell_array));
+         present = cell_array ;
+ 	for(i=0; i<reg_len+1; i++)
+ 	{
+ 		temp = (misr_type *) malloc(sizeof(misr_type));
+         	temp->f_free = 1;
+ 		temp->faulty = 1;
+         	temp->next = NULL;
+                 present->next = temp; 
+ 		present = present->next;
+ 	}
+ }
+ 
+ 
+ /*************************************************************
+ release linked list when finished
+ *************************************************************/
+ void kill_list(misr_type *present)
+ {
+         misr_type *temp;
+  
+         while(present)
+         {
+                 temp = present->next;
+                 free(present);
+                 present = temp;
+         }
+         return;
+ }
+ 
+ 
+ /************************************************************
+ make both MISR's identical to start the experiment
+ ************************************************************/
+ void init(misr_type *present)
+ {
+ 
+ 	while(present->next != NULL)
+ 	{
+ 		present->faulty = present->f_free;
+ 		present = present->next;
+ 	}
+ }
+ 
+ 
+ /***********************************************************
+ this proceedure is the workhorse of the program. Each time it
+ is called, it calculates the next value of each cell in the
+ MISR's and does this for hte number of times necessary.
+ ***********************************************************/
+ int simulate(int iterations, misr_type *present, double prob, char *structure)
+ {
+ 	misr_type *temp;
+ 	int different, savef_free, savefaulty;
+ 	int rem, quot, h, i, j;
+ 	long rand;
+ 	double randprob;
+ 
+ 	different = FALSE;
+ 	quot = (reg_len-1) / 31;
+         rem = (reg_len-1) % 31;
+ 	temp = present;
+ 
+ 	for(h=0; h<iterations; h++)
+ 	{
+ 		savef_free = 0;
+ 		savefaulty = 0;
+ 		for (i=0; i<quot; i++)
+ 		{
+ 			rand = lrand48();
+ 			for (j=0; j<31; j++)
+ 			{
+ 				if (structure[i*31 + j] == '1')
+ 				{
+ 					savef_free += temp->f_free;
+ 					savefaulty += temp->faulty;
+ 				}
+ 				temp->f_free = ((temp->next->f_free + rand) & BIN_MASK);
+ 				randprob = ((double)(lrand48() % 1000) / 1000);
+ 				if (prob > randprob) rand ^= BIN_MASK;
+ 				temp->faulty = ((temp->next->faulty + rand) & BIN_MASK);
+ 				temp = temp->next;
+ 				rand >>= 1;
+ 			}
+ 		}
+ 		rand = lrand48();
+ 		for (j=0; j<rem; j++)
+ 		{
+                         if (structure[quot*31 + j] == '1')
+                         {
+                                 savef_free += temp->f_free;
+                                 savefaulty += temp->faulty;
+                         }
+                         temp->f_free = ((temp->next->f_free + rand) & BIN_MASK);                                             
+                         randprob = ((double)(lrand48() % 1000) / 1000);                                if (prob > randprob) rand ^= BIN_MASK;
+                         temp->faulty = ((temp->next->faulty + rand) & BIN_MASK);
+                         temp = temp->next;
+                         rand >>= 1;
+                 }
+ 		rand = lrand48();
+ 		if (structure[reg_len - 1] == '1')
+ 		{
+ 			savef_free += temp->f_free;
+ 			savefaulty += temp->faulty;
+ 		}
+ 		temp->f_free = ((savef_free + rand) & BIN_MASK);
+ 		randprob = ((double)(lrand48() % 10000) / 10000);
+ 		if (prob > randprob) rand ^= BIN_MASK;
+ 		temp->faulty = ((savefaulty + rand) & BIN_MASK);
+ 
+ 		temp = present;
+ 	}
+ 
+ 	for (i=0; i<reg_len; i++)
+ 	{
+ 		if (temp->f_free != temp->faulty) different = TRUE;
+ 		temp = temp->next;
+ 	}
+ 	return different;
+ 
+ }


Index: llvm-test/SingleSource/Benchmarks/McGill/queens.c
diff -c /dev/null llvm-test/SingleSource/Benchmarks/McGill/queens.c:1.1
*** /dev/null	Tue Oct  5 15:58:50 2004
--- llvm-test/SingleSource/Benchmarks/McGill/queens.c	Tue Oct  5 15:58:37 2004
***************
*** 0 ****
--- 1,366 ----
+ /*
+ **  queens.c	--  Find solutions to the Eight-Queens chess problem.
+ **		    Roberto Sierra  3/19/84  Version 1.1
+ **
+ **  Description:
+ **	This program finds all the possible ways that N queens can
+ **	be placed on an NxN chessboard so that the queens cannot
+ **	capture one another -- that is, so that no rank, file or
+ **	diagonal is occupied by more than one queen.  By default,
+ **	the program prints the first solution it finds.  You can
+ **	use the -a option to print all solutions, or the -c option
+ **	just to count them.  The program allows the chess board
+ **	to be from 1x1 (trivial case) to 100x100.  Warning: the
+ **	larger the chess board, the longer it typically takes to
+ **	find each solution, even though there may be more of them.
+ **
+ **	This is a terrific example of the utility of recursion.  The
+ **	algorithm uses recursion to drastically limit the number
+ **	of board positions that are tested.  The program is able
+ **	to find all 8x8 queen solutions in a fraction of a second
+ **	(not counting print time).  The code makes no attempt to
+ **	eliminate symmetrical solutions, so the number of solutions
+ **	reported will always be higher than the actual number of
+ **	distinct solutions.
+ **
+ **
+ **  Usage:
+ **	queens [-ac] n
+ **
+ **	n	Number of queens (rows and columns). An integer from 1 to 100.
+ **	-a	Find and print all solutions.
+ **	-c	Count all solutions, but do not print them.
+ **
+ **	The output is sent to stdout.  All errors messages are
+ **	sent to stderr.  If a problem arises, the return code is -1.
+ **
+ **
+ **  Examples:
+ **
+ **	queens 8	## Show an 8x8 solution
+ **	8 queens on a 8x8 board...
+ **	 Q - - - - - - -
+ **	 - - - - Q - - -
+ **	 - - - - - - - Q
+ **	 - - - - - Q - -
+ **	 - - Q - - - - -
+ **	 - - - - - - Q -
+ **	 - Q - - - - - -
+ **	 - - - Q - - - -
+ **
+ **	queens -c 8	## Count all 8x8 solutions
+ **	8 queens on a 8x8 board...
+ **	...there are 92 solutions.
+ **
+ **	queens -a 4	## Show all 4x4 solutions
+ **	4 queens on a 4x4 board...
+ **	
+ **	Solution #1:
+ **	 - Q - -
+ **	 - - - Q
+ **	 Q - - -
+ **	 - - Q -
+ **	
+ **	Solution #2:
+ **	 - - Q -
+ **	 Q - - -
+ **	 - - - Q
+ **	 - Q - -
+ **	
+ **	...there are 2 solutions.
+ **
+ **
+ **  Build Instructions:
+ **	You'll need an ANSI C compiler (or the willingness to edit
+ **	the program a bit).  If you've got Gnu C, then you can
+ **	compile and load the program as follows:
+ **
+ **		gcc queens.c -ansi -o queens
+ **
+ **	[If you're using MPW on the Mac, define '-d MPW' on the
+ **	compile line so that background processing will occur.]
+ **
+ **
+ **  Algorithm:
+ **	In a 1984 Byte article, I ran across an interesting letter
+ **	from a high school student who was attempting to solve the
+ **	Eight Queens problem using a BASIC interpreter.  He had
+ **	developed a program which placed eight queens successively
+ **	on all sixty-four squares, testing for conflicts at each
+ **	iteration.  Of course, such a program would require 64^8
+ **	iterations (about 2.8x10^14 iterations).  Even in C on a,
+ **	fast CPU, this could take months or years.  Byte's answer was
+ **	to alter the loops so that the queens resided on separate
+ **	ranks, thereby reducing the number of iterations required
+ **	to find all solutions to 8^8 iterations (about 16 million).
+ **	More reasonable, but still requiring a chunk of CPU time.
+ **
+ **	I puzzled about this problem a bit, and came to realize that
+ **	this was still wasting a lot of CPU cycles.  Though I'm sure
+ **	others have come up with good algorithms, I decided to come
+ **	up with my own, with a particular eye on efficiency.  The
+ **	resulting algorithm finds all 8x8 solutions in a fraction
+ **	of a second (there are 92 solutions, including rotations).
+ **	On a Sun 4, it'll find all 365,596 solutions on a 14x14 board
+ **	in a bit over 2 minutes (printing them out requires extra
+ **	time, of course).  Even Byte's solution would require 14^14
+ **	iterations (about 10^16) which would take aeons.
+ **
+ **	My algorithm works as follows:
+ **	(1)  Place a queen in the top left corner.
+ **	(2)  Place another queen immediately below.
+ **	(3)  Test for conflicts.  If the second queen conflicts (it
+ **	     does at first), then move it one square to the right.
+ **	(4)  Loop step 3 until there are no conflicts.  Place
+ **	     the next queen on the board and recurse.
+ **	(5)  If any queen reaches the right edge of the board,
+ **	     remove it and 'pop' to the previous recursion level.
+ **	(6)  Now repeat these steps recursively until all eight
+ **	     queens (or however many) have been placed without
+ **	     conflict -- the result is a solution to the problem,
+ **	     which is counted and optionally printed.
+ **
+ **	Because conflicts are tested as the recursion proceeds,
+ **	this has the effect of 'pruning' the recursion so that
+ **	a large number of board positions are not even attempted.
+ **	The result is that the algorithm runs in reasonable time.
+ **
+ **	I used a few tricks to make the test-for-conflict code
+ **	extremely efficient -- there is no 'inner' loop to search
+ **	along ranks, files, or diagonals.  A series of arrays are
+ **	maintained instead which indicate which queen currently
+ **	'owns' each rank, file or diagonal.  This makes the
+ **	algorithm really fly, though the code is a little hard to
+ **	read.  Lastly, pointer arithmetic is used to reduce the
+ **	number of implicit multiplications used in array addressing.
+ **
+ **
+ **  Contact:
+ **	For queries regarding this program, contact Roberto Sierra
+ **	at any of the following addresses:
+ **
+ **		Roberto Sierra
+ **		bert at netcom.com   (preferred address)
+ **		73557.2101 at compuserve.com
+ **
+ **		Tempered MicroDesigns
+ **		P.O. Box 170638
+ **		San Francisco, CA  94117
+ **
+ **
+ **  Fine Print:
+ **	This program is in the public domain and can be used for
+ **	any purpose whatsoever, including commercial application.
+ **	[I'd like to hear what you do with it, though.]
+ **	Absolutely no warranty or liability is implied or extended
+ **	by the author.
+ **
+ **
+ **  Modification History:
+ **	PRS  3/19/84  v1.0 -- Original version.
+ **	PRS  7/25/93  v1.1 -- ANSIfied the code.  More efficient pointers.
+ */
+ 
+ 
+ #include <stdio.h>			/* Need standard I/O functions */
+ #include <stdlib.h>			/* Need exit() routine interface */
+ #include <string.h>			/* Need strcmp() interface */
+ #ifdef	MPW				/* Macintosh MPW ONLY */
+ #   include <CursorCtl.h>		/* Need cursor control interfaces */
+ #endif
+ 
+ #define MAXQUEENS 100 			/* Max number of queens */
+ #define MAXRANKS  MAXQUEENS		/* Max number of ranks (rows) */
+ #define MAXFILES  MAXQUEENS		/* Max number of files (columns) */
+ #define MAXDIAGS  (MAXRANKS+MAXFILES-1)	/* Max number of diagonals */
+ #define EMPTY	  (MAXQUEENS+1)		/* Marks unoccupied file or diagonal */
+ 
+ /* GLOBAL VARIABLES */
+ 
+ int queens;			/* Number of queens to place */
+ int ranks;			/* Number of ranks (rows) */
+ int files;			/* Number of files (columns) */
+ int printing = 1;		/* TRUE if printing positions */
+ int findall = 0;		/* TRUE if finding all solutions */
+ 
+ unsigned long solutions = 0;	/* Number of solutions found */
+ int queen[MAXRANKS];		/* File on which each queen is located */
+ int file[MAXFILES]; 		/* Which queen 'owns' each file */
+ int fordiag[MAXDIAGS];		/* Which queen 'owns' forward diagonals */
+ int bakdiag[MAXDIAGS];		/* Which queen 'owns' reverse diagonals */
+ char *progname = NULL;		/* The name of this program */
+ 
+ 
+ /* -------------------------- PROTOTYPES ----------------------- */
+ 
+ void pboard(void);
+ void find(register int level);
+ 
+ 
+ /*-------------------------- main() ----------------------------
+ **  MAIN program.  The main purpose of this routine is to deal
+ **  with decoding the command line arguments, initializing the
+ **  various arrays, and starting the recursive search routine.
+ */
+ void main(int argc, char **argv)
+ {
+    register int  i;				/* Loop variable */
+    register char *p;				/* Ptr to argument */
+    char *usage =
+ "Usage:  %s [-ac] n\n\
+ \tn\tNumber of queens (rows and columns). An integer from 1 to 100.\n\
+ \t-a\tFind and print all solutions.\n\
+ \t-c\tCount all solutions, but do not print them.\n";
+ 
+ #ifdef	MPW					/* Macintosh MPW ONLY */
+    InitCursorCtl(0);				/* Enable cursor control */
+ #endif
+ 
+    progname = argv[0];				/* Name of the program */
+ 
+    /****   DECODE COMMAND LINE ARGUMENTS   ****/
+    printing = 0;
+    queens = 14;
+    findall = 1;
+ 
+    for(i = 1; i < argc; ++i) {			/* Scan through arguments */
+       p = argv[i];				/* Ptr to base of argument */
+       if(*p == '-') {				/* Command line option? */
+          while(*++p) {				/* Loop through characters */
+             switch(*p) {			/* What is the character */
+                case 'c':			/* '-c' option */
+                   printing = 0;			/* Counting, not printing */
+                case 'a':			/* '-a' option */
+                   findall = 1;			/* Find all solutions */
+                   break;
+                default:				/* Illegal option */
+                   fprintf(stderr,"%s: Illegal option '%s'\n",progname,argv[i]);
+                   fprintf(stderr,usage,progname);
+                   exit(-1);
+             }					/* End of switch */
+          }					/* End of loop */
+       }						/* End of option test */
+       else {
+          if(sscanf(p,"%d",&queens) != 1) {	/* Read integer argument */
+             fprintf(stderr,"%s: Non-integer argument '%s'\n",progname,p);
+             exit(-1);
+          }
+          if(queens <= 0) {			/* N must be positive */
+             fprintf(stderr,"%s: n must be positive integer\n",progname);
+             exit(-1);
+          }
+          if(queens > MAXQUEENS) {		/* N can't be too large */
+             fprintf(stderr,"%s: Can't have more than %d queens\n",
+                progname, MAXQUEENS);
+             exit(-1);
+          }
+       }						/* End of argument test */
+    }						/* End of argument scan loop */
+    if(!queens) {
+       fprintf(stderr,"%s: Missing n argument\n",progname);
+       fprintf(stderr,usage,progname);
+       exit(-1);
+    }
+ 
+    ranks = files = queens;			/* NxN board for N queens */
+    printf("%d queen%s on a %dx%d board...\n",
+       queens, queens > 1 ? "s" : "", ranks, files);
+    fflush(stdout);
+ 
+    /* Initialization */
+    solutions = 0;				/* No solutions yet */
+    for(i = 0; i < MAXFILES; ++i) file[i] = EMPTY;
+    for(i = 0; i < MAXDIAGS; ++i) fordiag[i] = bakdiag[i] = EMPTY;
+ 
+    /* Find all solutions (begin recursion) */
+    find(0);
+    if(printing && solutions) putchar('\n');
+ 
+    /* Report results */
+    if(solutions == 1) printf("...there is 1 solution\n");
+    else printf("...there are %ld solutions\n", solutions);
+ 
+    exit(0);					/* No errors */
+ }
+ 
+ 
+ /***********************/
+ /****	ROUTINES    ****/
+ /***********************/
+ 
+ /*------------------------- pboard() ---------------------------
+ **  This routines prints the board for a particular solution.
+ **  The output is sent to stdout.
+ */
+ void pboard(void)
+ {
+    register int i, j;				/* Rank/File indices */
+ 
+    if(findall)  				/* Only if searching for all */
+       printf("\nSolution #%lu:\n",solutions);	/* Print solution number */
+ 
+    for(i = 0; i < ranks; ++i) {			/* Loop through all ranks */
+       for(j = 0; j < files; ++j) {		/* Loop through all files */
+          putchar(' ');				/* Output a space */
+          if(j == queen[i]) putchar('Q');	/* Output Q for queen... */
+          else putchar('-');			/* or '-' if empty */
+       }
+       putchar('\n');				/* Break line */
+    }
+    fflush(stdout);				/* Flush solution to output */
+ }
+ 
+ 
+ /*-------------------------- find() ----------------------------
+ **  FIND is the recursive heart of the program, and finds all
+ **  solutions given a set of level-1 fixed queen positions.
+ **  The routine moves a single queen through all files (columns)
+ **  at the current rank (recursion level).  As the queen is moved,
+ **  conflict tests are made.  If the queen can be placed without
+ **  conflict, then the routine recurses to the next level.  When
+ **  all queens have been placed without conflict, a solution is
+ **  counted and reported.
+ */
+ void find(register int level)
+ {
+    register int f;			/* Indexes through files */
+    register int *fp, *fdp, *bdp;	/* Ptrs to file/diagonal entries */
+ 
+ #ifdef	MPW				/* Macintosh MPW ONLY */
+    if(level & 7 == 0)			/* Periodically break for... */
+       SpinCursor(1);			/* background processing */
+ #endif
+ 
+    if(level == queens) {		/* Placed all queens? Stop. */
+       ++solutions;			/* This is a solution! */
+       if(printing) pboard();		/* Print board if printing */
+       if(!findall) exit(0);		/* May stop after first solution */
+ #ifdef	MPW				/* Macintosh MPW ONLY */
+       SpinCursor(1);			/* background processing */
+ #endif
+    }
+    else {				/* Not at final level yet */
+       for(				/* Move queen through all files */
+          f = 0,				/* Queen starts at left (file 0) */
+          fp = file,			/* Ptr to base of file array */
+          fdp = &fordiag[level],		/* Ptr to first fwd diag entry */
+          bdp = &bakdiag[level+files-1]	/* Ptr to first bak diag entry */
+          ;
+          f < files			/* Loop through all files */
+          ;
+          ++f,				/* Advance index */
+          ++fp, ++fdp, --bdp		/* Advance pointers */
+       ) {
+          if(*fp >= level && 		/* No queen on the file? */
+             *fdp >= level && *bdp >= level	/* No queens on diagonals? */
+ 	 ) {
+             queen[level] = f;		/* Note new position of queen */
+             *fp = *fdp = *bdp = level;	/* Place queen on file & diags */
+             find(level+1);		/* This level OK, recurse to next */
+             *fp = *fdp = *bdp = EMPTY;	/* Remove queen from file & diags */
+          }				/* End of conflict test */
+       }					/* End of file loop */
+    }					/* End if (level == queens) */
+ }
+ 
+ 






More information about the llvm-commits mailing list