]> git.cworth.org Git - wordgame/blobdiff - dict.c
Add printing to dict interface. Breakup grid prints by letter count.
[wordgame] / dict.c
diff --git a/dict.c b/dict.c
index 715e48f8deaa52c73bf499a3aae856dcc16a1e24..c364cb8110f066c9fbc71f65317fbb526778da84 100644 (file)
--- 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)
 {
@@ -329,14 +331,94 @@ dict_cursor_resolve (dict_cursor_t cursor)
     return &trie->flags;
 }
 
-void
+/* 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);
+
+    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);
 
-    trie_print (dict, &string, NULL);
+    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;
 }