Created
April 10, 2017 19:21
-
-
Save 44100hertz/067c1739201e80e4ea141ce18b01dbae to your computer and use it in GitHub Desktop.
C word search solver exercise
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <stdlib.h> | |
char *wordgrid = "thiswatsoahgfgdt"; | |
const int grid_size = 4; | |
// List of words | |
char** wl; | |
int num_wl; | |
// Resizable collection of found letters | |
int* found; | |
int num_found; | |
int cap_found = 100; | |
// Letter accumulator for searching | |
char* accum; | |
void init_words(char* path) | |
{ | |
FILE* dict = fopen(path, "r"); | |
// Count the number of valid words | |
num_wl = 0; | |
char* line = malloc(grid_size * sizeof(char)); // Temp line for reading | |
size_t len = grid_size; | |
ssize_t read; | |
while((read = getline(&line, &len, dict)) != -1) { | |
if(read-1 <= grid_size) num_wl++; | |
len = grid_size; | |
} | |
// Allocate wordlist to correct size | |
wl = malloc(num_wl * sizeof(char*)); | |
// Re-read file and copy valid words to list | |
rewind(dict); | |
int index = 0; | |
len = grid_size; | |
while((read = getline(&line, &len, dict)) != -1) { | |
if (read-1 <= grid_size) { | |
wl[index++] = strndup(line, read-1); | |
} | |
len = grid_size; | |
} | |
free(line); | |
fclose(dict); | |
} | |
int find_word(char* word, int len) | |
{ | |
for(int i=0; i<num_wl; ++i) { | |
if (strcmp(word, wl[i]) == 0) { | |
return i; | |
} | |
} | |
return -1; | |
} | |
enum {SEARCH_UP, SEARCH_DOWN, SEARCH_LEFT, SEARCH_RIGHT}; | |
void search_one(int x, int y, int direction) | |
{ | |
int num_ltr = 0; | |
memset(accum, 0, 4); | |
while (x >= 0 && x < grid_size && y >= 0 && y < grid_size) { | |
int index = y * grid_size + x; | |
accum[num_ltr] = wordgrid[index]; | |
num_ltr++; | |
int i; | |
int already_found = 0; | |
for(i=0; i<num_found; ++i) { | |
if(strcmp(wl[found[i]], accum) == 0) { | |
already_found = 1; | |
break; | |
} | |
} | |
if (!already_found && (i = find_word(accum, num_ltr)) != -1) { | |
if(num_found-1 == cap_found) { | |
int* orig_end = (int*)(found + (cap_found * sizeof(int))); | |
size_t added_len = cap_found * sizeof(int); | |
cap_found *= 2; | |
found = realloc(found, cap_found * sizeof(int)); | |
memset(orig_end, 0, added_len * sizeof(int)); | |
} | |
found[num_found++] = i; | |
} | |
switch(direction) { | |
case SEARCH_UP: y += 1; break; | |
case SEARCH_DOWN: y -= 1; break; | |
case SEARCH_LEFT: x -= 1; break; | |
case SEARCH_RIGHT: x += 1; break; | |
} | |
} | |
} | |
void search_words() | |
{ | |
found = malloc(cap_found * sizeof(int)); | |
for(int y=0; y<grid_size; ++y) { | |
for(int x=0; x<grid_size; ++x) { | |
search_one(x, y, SEARCH_UP); | |
search_one(x, y, SEARCH_DOWN); | |
search_one(x, y, SEARCH_LEFT); | |
search_one(x, y, SEARCH_RIGHT); | |
} | |
} | |
} | |
void print_found() | |
{ | |
for(int i=0; i<num_found; ++i) { | |
printf("%s\n", wl[found[i]]); | |
} | |
} | |
int main() | |
{ | |
init_words("/usr/share/dict/words"); | |
accum = malloc(grid_size * sizeof(char)); | |
search_words(); | |
print_found(); | |
for(int i=0; i<num_wl; ++i) free(wl[i]); | |
free(wl); | |
free(found); | |
free(accum); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment