Combine the module: count word frequencies from an array of tokens.
The boilerplate declares:
``c
#define WF_BUCKETS 16
typedef struct WFNode {
const char *word; /* the table strdups it: it OWNS its keys */
size_t count;
struct WFNode *next;
} WFNode;
typedef struct { WFNode *buckets[WF_BUCKETS]; size_t distinct; } WF;
void wf_init(WF *w);
int wf_count(WF *w, const char *word); /* 0 ok, -1 bad args/oom */
/* returns 1 and fills count+word_out (the table's OWNED copy, valid
until wf_destroy) if present; 0 if absent */
int wf_lookup(const WF *w, const char *word, size_t *count, const char **word_out);
size_t wf_distinct(const WF *w);
void wf_destroy(WF *w); /* frees every node AND every strdup'd key */
``
The table must own its keys (strdup on first sight) — that is the
ownership seam: values are plain counts, but keys are owned.
Difficulty: intermediate