Skip to content

Instantly share code, notes, and snippets.

@samwhaleIV
Created November 8, 2019 23:20
Show Gist options
  • Save samwhaleIV/df9e86f710ab586488b1266014c91530 to your computer and use it in GitHub Desktop.
Save samwhaleIV/df9e86f710ab586488b1266014c91530 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
static const char* DICTIONARY_FILE = "C:\\Users\\Samuel\\Documents\\c-shit\\words_alpha.txt";
static const int ALPHABET_SIZE = 26;
static const int ALPHABET_ORDER[] = {
//Conforms to "etaoinshrdlcumwfgypbvkjxqz"
//(There's probably a way to generate this data at compile time within the source file?)
2,19,11,9,0,15,16,7,4,22,21,10,13,5,3,18,24,8,6,1,12,20,14,23,17,25
};
typedef struct CharacterNode {
char character;
struct CharacterNode* node;
} CharacterNode;
typedef struct StringListNode {
char* characters;
struct StringListNode* node;
} StringListNode;
CharacterNode* GetCharacterNode() {
return malloc(sizeof(CharacterNode));
}
StringListNode* GetStringListNode() {
return malloc(sizeof(StringListNode));
}
unsigned char* CountLetters(char* letters) {
unsigned char* counters = calloc(ALPHABET_SIZE,sizeof(unsigned char));
char letter;
int index = 0;
do {
letter = letters[index];
if(letter == '\0') {
break;
}
index++;
counters[ALPHABET_ORDER[letter - 'a']] += 1;
} while(1);
return counters;
}
char* FlattenString(CharacterNode* rootNode, int length) {
CharacterNode* node = rootNode;
char* characterArray = malloc((length + 1) * sizeof(char));
int index = 1;
do {
int character = node->character;
characterArray[length - index] = (char)character;
index += 1;
node = node -> node;
} while(node != NULL);
characterArray[length] = '\0';
return characterArray;
}
int main(int argumentCount, char* arguments []) {
if(argumentCount < 2) {
return EXIT_FAILURE;
}
char* word = arguments[1];
FILE* file = fopen(DICTIONARY_FILE, "r");
if(!file) {
printf("Error: Could not open dictionary file");
return EXIT_FAILURE;
}
printf("%s\n", "Opened dictionary file..");
int characterFeed;
char* characters;
int wordLength = 0;
CharacterNode* nextNode;
StringListNode* newWordNode;
CharacterNode* string = NULL;
StringListNode* allWords = NULL;
refreshCharacterFeed:
characterFeed = getc(file);
switch (characterFeed) {
case '\r': {
goto refreshCharacterFeed;
}
case EOF: {
if(string == NULL) {
goto endFileRead;
}
//Fall-through to case '\n'
}
case '\n': {
characters = FlattenString(string, wordLength);
newWordNode = GetStringListNode();
newWordNode->characters = characters;
newWordNode->node = allWords;
wordLength = 0;
allWords = newWordNode;
do {
nextNode = string->node;
free(string);
string = nextNode;
} while(string != NULL);
string = NULL;
if(characterFeed == EOF) {
/*
This check EOF/psuedo-duplicate switch case could
be optimized away if I knew structuring in C better
*/
goto endFileRead;
}
goto refreshCharacterFeed;
}
default: {
nextNode = GetCharacterNode();
nextNode->node = string;
nextNode->character = characterFeed;
string = nextNode;
wordLength += 1;
goto refreshCharacterFeed;
}
}
endFileRead:
fclose(file);
printf("Closed dictionary file.");
StringListNode* anagramMatches;
anagramMatches = NULL;
StringListNode* nextMatch;
unsigned char* letterCounts = CountLetters(word);
unsigned char* letterCountTest;
do {
characters = allWords->characters;
letterCountTest = CountLetters(characters);
int i = 0;
for(i = 0;i < ALPHABET_SIZE;i++) {
if(letterCountTest[i] != letterCounts[i]) {
break;
}
}
if(i == ALPHABET_SIZE) {
nextMatch = GetStringListNode();
nextMatch->characters = allWords->characters;
nextMatch->node = anagramMatches;
anagramMatches = nextMatch;
}
allWords = allWords->node;
} while(allWords != NULL);
nextMatch = NULL;
if(anagramMatches != NULL) {
printf("\nMatches:\n");
do {
printf("%s\n", anagramMatches->characters);
anagramMatches = anagramMatches->node;
} while(anagramMatches != NULL);
}
else {
printf("\nNo matches found.");
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment