/*  program to generate word squares */
/*  hopefully faster than acro  */
/*  Manojkumar Saranathan c 1997 */

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAX_SIZE 8
#define MAX_WORD_SIZE 256
#define WORD_BLK 4096

char words[MAX_SIZE][MAX_SIZE];
char **words2;
int acro_size;
int num_words;

main(argc,argv)
int argc;
char *argv[];
{
FILE *fp, *fopen();
int i,j;
char *template;
char fname[256];
char buffer[8];

if (argc == 2)
 {
    template = words[0]+1;
    acro_size = strlen(argv[1]);
    strcpy(words[0], argv[1]);
 }
else if (argc == 1)
 {
    template = "abcdefghijklmnopqrstuvwxyz";
    printf("Word square length: ");
    scanf("%d",&acro_size);
    printf("\n");
 }
else
 {
    printf("Acrostic by Manoj Saranathan c 1997\n");
    printf("Usage: acro <optional startword>");
    exit(1);
 }

if (acro_size > 8)
 {
    printf("Maximum length of word square is 8\n");
    exit(1);
 }

/*** Allocate memory for 2D array ***/
if ((words2 = (char **) malloc (WORD_BLK*acro_size*sizeof (char *))) == (char **)
NULL)
 {
    fprintf (stderr, "Insufficient memory.  malloc() returned NULL.\n");    exit (-1);
 }
for (i = 0; i< WORD_BLK*acro_size; i++)
 {
    if ((words2[i] = (char *) malloc (MAX_SIZE*sizeof (char ))) == (char *) NULL)
    {
         fprintf (stderr, "Insufficient memory.  malloc() returned NULL.\n");    exit (-1);
    }    
 }
sprintf(fname,"words.%d",acro_size);
if ((fp = fopen (fname, "r")) == NULL)
 {
    fprintf (stderr, "Error opening word file <words.%d>\n",acro_size);
    exit(1);
 }
printf("Loading words ...  ");
i=0;
while (fgets (buffer, MAX_WORD_SIZE, fp) != (char *) NULL)
 {
    if(strchr(template,buffer[0]))
     {
        j = (int) strlen (buffer) - 1;
        buffer[j--] = '\0';
        strcpy(words2[i],buffer);
        i++;
     }
 }
printf("Done.\n");
num_words = i;
if (argc == 1)
 {
    for (i = 0; i<num_words; i++)
     {
        printf("Starting word %s\n",words2[i]);
        strcpy(words[0],words2[i]);
        wsquare(acro_size);
     }
 }
else
    wsquare(acro_size);

}
wsquare(level)
int level;
{
int i,j,k;
int num_cwords;
FILE *fp;
char search[MAX_SIZE];
char new[MAX_SIZE];
char temp[MAX_SIZE];
char fname[MAX_WORD_SIZE];
char buffer[MAX_SIZE];
char **cwords;

if (level > 1)
 {
 /*** generate the grep search string based on depth (level) ***/
    *search = 0;
    for(i = 0; i < acro_size-level+1; i++)
     {
        sprintf(temp,"%c",words[i][acro_size-level+1]);
        strcat(search,temp);
     }

/*** allocate space for cwords ***/
    if ((cwords = (char **) malloc (WORD_BLK*sizeof (char *))) == (char **) NULL)
     {
        fprintf (stderr, "Insufficient memory.  malloc() returned NULL.\n");    exit (-1);
     }  

    for (i = 0; i< WORD_BLK; i++)
     {
        if ((cwords[i] = (char *) malloc (MAX_SIZE*sizeof (char ))) == (char *) NULL)
         {
             fprintf (stderr, "Insufficient memory.  malloc() returned NULL.\n");
   exit (-1);
         }   
     }    

/*** copy list of candidate words into cwords ***/
    j = 0;
    for(k =0; k<num_words; k++)
     {
        strncpy(new,words2[k],strlen(search));
        if (!strncmp(search,new,strlen(search)))
         {
            strcpy(cwords[j],words2[k]);
            j++;
         }
     }    
    num_cwords = j;

    for(j=0; j<num_cwords; j++)
     {

       if(look_ahead(level, cwords[j]))
        {
            strcpy(words[acro_size-level+1],cwords[j]);
            if (level == 2)
             {
                printf("\n SQUARE \n");
                for (i = 0; i< acro_size; i++) printf("%s\n",words[i]);
             }
            else
             {  
                wsquare(level-1);
             }
        }
     }   

    for (i = 0; i< WORD_BLK; i++)
     {
        free(cwords[i]);
     }

 }
}


look_ahead(level, buffer)
int level;
char *buffer;

{
int i,j,k;
char search[MAX_SIZE];
char temp[MAX_SIZE];
char temp2[256];
char new[MAX_SIZE];
int val=0;
FILE *fp2;

if(level == 2) return(1);
for(j = acro_size-level+2; j < acro_size; j++)
 {
    *search = 0;
    for(i = 0; i < acro_size-level+1; i++)
     {
        sprintf(temp,"%c",words[i][j]);
        strcat(search,temp);
     }
        sprintf(temp,"%c",buffer[j]);
        strcat(search,temp);
    sprintf(temp2,"words.%d", acro_size);
    val = 0;
    for(k =0; (k<num_words)&&(val==0); k++)
    {
        strncpy(new,words2[k],strlen(search));
        if (!strncmp(search,new,strlen(search))) val = 1;
    }
        if (val == 0) return(0);
 }
return(1);
}