/* l6.c - Don Yang (uguu.org) 04/17/05 */ #include #include #include #include typedef union { char *w; int i; } Element; typedef struct { int size, max; Element *d; } List; List Index[26], AllWords; char *t, *text; int size, r, i, j, k, k0, k1, c0, column, margin; FILE *infile; int SLen(char *d) { for(r = 0; *d++; r++); return r; } void PutChar(int c) { putchar(c); } void PutStr(char *d) { for(; *d; PutChar(*d++)); } void Reset(List *l) { l->d = NULL; l->size = l->max = 0; } void AddToList(List *l, char *d) { Element *tmp, *a, *b; if( !l->d ) { if( !(l->d = (Element*)malloc((l->max = 32) * sizeof(Element))) ) return; } if( l->size + 1 > l->max ) { if( !(tmp = (Element*)malloc((l->max * 2) * sizeof(Element))) ) return; a = tmp; b = l->d; for(r = l->size; r--; a++->i = b++->i); free(l->d); l->d = tmp; l->max *= 2; } l->d[l->size++].w = d; } void FreeList(List *l) { if( l->d ) free(l->d); } int PartialMatch(char *a, char *b) { for(r = 0; *a && *b && *a == *b; a++, b++, r++); return r; } int main(int argc, char **argv) { if( argc < 2 ) { PutStr(" [width] [...]\n"); return 0; } if( (infile = fopen(argv[1], "rb")) == NULL ) { PutStr("open error\n"); return 0; } fseek(infile, 0, 2); if( (size = ftell(infile)) < 1 ) return fclose(infile); fseek(infile, 0, 0); if( !(text = (char*)malloc(size + 1)) ) return fclose(infile); fread(text, size, 1, infile); text[size] = 0; fclose(infile); for(i = 0; i < 26; Reset(&Index[i++])); Reset(&AllWords); for(t = text; size--; *(t++) = 0) { if( isalpha(*t) ) { *t = tolower(*t); AddToList(&Index[*t - 97], (char*)AllWords.size); AddToList(&AllWords, t); for(; size-- ? isalnum(*t) : 0; t++) *t = tolower(*t); size++; } } if( (size = (argc > 2) ? atoi(argv[2]) : 80) < 1 ) size = 80; srand(time(0)); if( argc > 3 ) { for(; argc-- > 3;) { PutChar(10); t = argv[argc]; column = SLen(t); for(i = 0; i < column; i++) t[i] = tolower(t[i]); PutStr(t); for(margin = size - 1 - SLen(argv[argc - 1]); column < margin; column += 1 + SLen(t)) { do { c0 = *t - 97; do { i = rand() % AllWords.size; if( c0 < 0 || c0 > 25 ) break; if( !Index[c0].size ) break; i = Index[c0].d[rand() % Index[c0].size].i; k0 = PartialMatch(t, AllWords.d[i].w); for(j = 0; j < Index[c0].size / 2; j++) { k = Index[c0].d[rand() % Index[c0].size].i; if( (k1 = PartialMatch(t, AllWords.d[k].w)) > k0 ) { i = k; k0 = k1; } } i = (i + 1) % AllWords.size; } while(0); } while( column + 1 + SLen(AllWords.d[i].w) >= size ); PutChar(32); PutStr(t = AllWords.d[i].w); } } } else { column = size; for(i = 0; i < AllWords.size; i++) { if( (column + 1 + SLen(AllWords.d[i].w)) >= size ) { PutChar(10); column = 0; } else { PutChar(32); column++; } PutStr(AllWords.d[i].w); column += SLen(AllWords.d[i].w); } } PutStr("\n\n"); for(i = 0; i < 26; FreeList(&Index[i++])); FreeList(&AllWords); free(text); return 0; }