X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=dict.c;h=c364cb8110f066c9fbc71f65317fbb526778da84;hb=2d604d8b8a380f7f3028c234282bfdcf12f95dad;hp=00d54e04036b79576a4fa2dc155853ee9d663864;hpb=70914305c0fe98948ba7e105a220fe7a36a62fec;p=wordgame diff --git a/dict.c b/dict.c index 00d54e0..c364cb8 100644 --- a/dict.c +++ b/dict.c @@ -180,22 +180,47 @@ trie_find (trie_t *trie, return trie; } +int +trie_count (trie_t *trie, + trie_predicate_t predicate) +{ + int i; + int count = 0; + + if ((predicate) (trie)) + count = 1; + + for (i = 0; i < 26; i++) { + if (trie->next[i] == NULL) + continue; + + count += trie_count (trie->next[i], predicate); + } + + return count; +} + int trie_print (trie_t *trie, string_t *string, - trie_predicate_t predicate) + trie_predicate_t predicate, + int length, + int min_length, + int max_length) { char c; int i; int count = 0; - if (trie->flags & TRIE_FLAGS_IS_WORD - && (predicate == NULL || predicate (trie))) + if (length >= min_length && (predicate) (trie)) { count = 1; printf ("%s ", string->s); } + if (length == max_length) + return count; + /* Loop over each element, appending the character and recursing. */ for (i = 0; i < 26; i++) { if (trie->next[i] == NULL) @@ -204,37 +229,14 @@ trie_print (trie_t *trie, c = TRIE_INDEX_TO_CHAR (i); string_append_char (string, c); - count += trie_print (trie->next[i], string, predicate); + count += trie_print (trie->next[i], string, predicate, + length + 1, min_length, max_length); string_chop (string); } return count; } -bool_t -trie_seen_predicate (trie_t *trie) -{ - return (trie->flags & TRIE_FLAGS_SEEN); -} - -int -trie_print_seen (trie_t *trie, string_t *word) -{ - return trie_print (trie, word, trie_seen_predicate); -} - -bool_t -trie_unseen_predicate (trie_t *trie) -{ - return (! trie_seen_predicate (trie)); -} - -int -trie_print_unseen (trie_t *trie, string_t *word) -{ - return trie_print (trie, word, trie_unseen_predicate); -} - void dict_init (dict_t *dict) { @@ -283,14 +285,140 @@ dict_add_words_from_file (dict_t *dict, fclose (file); } -void +dict_entry_t * +dict_lookup (dict_t *dict, + const char *word) +{ + trie_t *trie; + + trie = trie_find (dict, word); + if (trie == NULL) + return NULL; + else + return &trie->flags; +} + +/* Yes, this function is rather silly. I have it here in the hope that + * it could be used for some better type-checking, (if only C had such + * a thing). */ +dict_cursor_t +dict_root (dict_t *dict) +{ + return dict; +} + +dict_cursor_t +dict_cursor_next (dict_cursor_t cursor, + char next) +{ + trie_t *trie = cursor; + + if (trie == NULL) + return DICT_CURSOR_NIL; + + return trie->next[TRIE_CHAR_TO_INDEX (next)]; +} + +dict_entry_t * +dict_cursor_resolve (dict_cursor_t cursor) +{ + trie_t *trie; + + if (cursor == DICT_CURSOR_NIL) + return NULL; + + trie = cursor; + return &trie->flags; +} + +/* XXX: This static function pointer is really nasty and definitely + * un-thread safe. What I really want it a lambda so I can construct a + * composite predicate on the fly. Oh well... */ +static dict_entry_predicate_t dict_entry_predicate = NULL; + +static bool_t +dict_predicate (trie_t *trie) +{ + dict_entry_t *entry; + + entry = dict_cursor_resolve (trie); + if (! DICT_ENTRY_IS_WORD (entry)) + return FALSE; + + if (dict_entry_predicate) + return (dict_entry_predicate) (*entry); + + return TRUE; +} + +int +dict_count (dict_t *dict, + dict_entry_predicate_t predicate) +{ + dict_entry_predicate = predicate; + return trie_count (dict, dict_predicate); +} + +int dict_print (dict_t *dict) { + int count; + string_t string; + + string_init (&string); + + dict_entry_predicate = NULL; + count = trie_print (dict, &string, dict_predicate, + 0, 0, -1); + + string_fini (&string); + + return count; +} + +int +dict_print_if (dict_t *dict, + dict_entry_predicate_t predicate) +{ + int count; string_t string; string_init (&string); - trie_print (dict, &string, NULL); + dict_entry_predicate = predicate; + count = trie_print (dict, &string, dict_predicate, + 0, 0, -1); string_fini (&string); + + return count; +} + +int +dict_print_by_length_if (dict_t *dict, + dict_entry_predicate_t predicate) +{ + int length, total, words, count = 0; + string_t string; + + string_init (&string); + + dict_entry_predicate = predicate; + + total = trie_count (dict, dict_predicate); + + length = 1; + do { + words = trie_print (dict, &string, dict_predicate, + 0, length, length); + if (words) { + printf ("\n"); + count += words; + } + length++; + } while (count < total); + + string_fini (&string); + + return count; }