/* Problem 7--Jumble! This wasn't particularly hard, just a bit tedious. Just follow the rules to decide whether a word is good, fair, or poor. Note: one of the data sets gives a different answer using my solution from the distributed solution. It sure looks to me, though, that my solution is right and theirs is in error. */ #include #include #include #define VCSIZE 12 #define CCSIZE 37 typedef struct LLC { /* ANSI C has no standard routine for reading a string of unspecified length, so this data structure accomplishes this. */ char c; struct LLC *n; } LLC; int main (int argc, char **argv); int ReadString (char **A); int IsVowel (char c); int Good (char *J); int GoodVowel (char *J); int GoodCons (char *J); int Match (char *W, char *J); FILE *in, *out; /* The acceptable vowel and consonant combinations */ char *VowelComb[VCSIZE] = {"AI","AY","EA","EE","EO","IO","OA","OO","OY", "YA","YO","YU"}; char *ConsComb[CCSIZE] = {"SCH","SCR","SHR","THR","BL","BR","CH","CK", "CL","CR","DR","FL","FR","GH","GL","GR","KL", "KR","KW","PF","PL","PR","SC","SH","SK","SL", "SM","SN","SP","SQ","ST","SW","TH","TR","TW", "WH","WR"}; int main (int argc, char **argv) { char *Word, *Jumble; in = fopen ("prob7.in","r"); out = fopen ("prob7.out","w"); while (ReadString (&Word)) { /* Get the word and the jumble. */ ReadString (&Jumble); switch (Match (Word,Jumble)) { /* Print appropriate message. */ case 0 : {fprintf (out,"\"%s\" is not a scramble of \"%s\"\n\n", Jumble,Word); break;} case 1 : {fprintf (out,"\"%s\" is a good scramble of \"%s\"\n\n", Jumble,Word); break;} case 2 : {fprintf (out,"\"%s\" is a poor scramble of \"%s\"\n\n", Jumble,Word); break;} case 3 : {fprintf (out,"\"%s\" is a fair scramble of \"%s\"\n\n", Jumble,Word); break;} } } fclose (in); fclose (out); return EXIT_SUCCESS; } /* ReadString reads in a string of unspecified length into a linked list and then converts it to a char array. It returns 0 if the data is exhausted, 1 otherwise. */ int ReadString (char **A) { int c, ct=0; LLC *head = NULL, *t; do { c = fgetc (in); /* Read characters into linked list until EOF or */ if (c==EOF) break; /* EOLN is found. */ t = malloc (sizeof (LLC)); t->n = head; head = t; if (c >= 'A' && c <= 'Z') t->c = c; else t->c = 0; ct++; } while (c!='\n'); if (c!=EOF) *A = malloc (ct*sizeof(char)); /* Build string from list */ while (head != NULL) { if (c!=EOF) (*A)[--ct] = head->c; t = head; head=t->n; free (t); } return c!=EOF; } /* IsVowel returns a boolean indicating whether the given letter is a vowel. */ int IsVowel (char c) { return c=='A' || c=='E' || c=='I' || c=='O' || c=='U' || c=='Y'; } /* returns a boolean indicating whether the given word is "good" */ int Good (char *J) { if (IsVowel (J[0])) return GoodVowel (J); return GoodCons (J); } /* GoodVowel accepts a word and returns true provided that the word is good and begins with a vowel, false otherwise. */ int GoodVowel (char *J) { int i; if (J[0]==0) return 1; if (!IsVowel (J[0])) return 0; /* doesn't begin with a vowel */ for (i=0;i < VCSIZE; i++){ /* Go through valid double vowels */ if (strlen (VowelComb[i]) <= strlen (J) && memcmp (VowelComb[i],J,strlen(VowelComb[i]))==0) return GoodCons (&(J[strlen(VowelComb[i])]));} return GoodCons (&(J[1]));/*return whether rest of string is GoodCons*/ } /* GoodCons accepts a word and returns true provided that the word is good and begins with a consonant, false otherwise. */ int GoodCons (char *J) { int i; if (J[0]==0) return 1; if (IsVowel (J[0])) return 0; /* doesn't begin with a consonant */ for (i=0;i < CCSIZE; i++) /* Go through valid double consonants */ if (strlen (ConsComb[i]) <= strlen (J) && memcmp (ConsComb[i],J,strlen(ConsComb[i]))==0) return GoodVowel (&(J[strlen(ConsComb[i])])); if (J[0]==J[1]) return GoodVowel (&(J[2])); /* Check for rep. cons. */ return GoodVowel (&(J[1]));/* return whether rest is GoodVowel */ } /* Match takes a word and a jumble and returns 0 if not a jumble, 1 if it is a good jumble, 2 if it is a poor jumble, and 3 if it is a fair jumble. */ int Match (char *W, char *J) { int i, m, g; if (strcmp (W,J)==0) return 0; g = Good (J); for (m=0,i=0; i < strlen (W); i++) if (W[i]==J[i]) m++; /* Count matches in word and jumble */ if (g && m==0) return 1; if (!g && (W[0]==J[0] || m>=2)) return 2; return 3; }