Skip to content

Instantly share code, notes, and snippets.

@44100hertz
Created April 10, 2017 19:21
Show Gist options
  • Save 44100hertz/067c1739201e80e4ea141ce18b01dbae to your computer and use it in GitHub Desktop.
Save 44100hertz/067c1739201e80e4ea141ce18b01dbae to your computer and use it in GitHub Desktop.
C word search solver exercise
#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