Created
November 8, 2019 23:20
-
-
Save samwhaleIV/df9e86f710ab586488b1266014c91530 to your computer and use it in GitHub Desktop.
This file contains 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 <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