Skip to content
Snippets Groups Projects
Commit ea01b96a authored by Hye Won Park's avatar Hye Won Park
Browse files

Upload New File

parent fc9696d3
No related branches found
No related tags found
No related merge requests found
#define _POSIX_C_SOURCE 200809L
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIDES 26
#define MAX_ALPHABET 10
#define INITIAL_DICT_SIZE 10000
#define MAX_WORD_SIZE 100
typedef struct {
char sides[MAX_SIDES][MAX_ALPHABET + 1];
int numSides;
} Board;
void loadBoard(const char *fileName, Board *board);
char **loadDict(const char *fileName, int *num);
int isValidWord(const char *inputWord, char **dict, Board *board, int dictNum, int *trackChar);
void freeMemory(char **dict, int dictNum);
int main(int argc, char *argv[]) {
if (argc != 3) {
printf("Usage: ./letter-boxed <board file> <dictionary file>\n");
exit(1);
}
Board board;
loadBoard(argv[1], &board); // load letter boxed board with board file input
int dictNum = 0; // number of words in dictionary
char **dict = loadDict(argv[2], &dictNum); // store dictionary words in 2d array
int trackChar[26] = {0}; // array to track characters in word
char currInput[MAX_WORD_SIZE];
char prevInput[MAX_WORD_SIZE] = "";
while (scanf("%s", currInput) != EOF) {
if (prevInput[0] != '\0' && prevInput[strlen(prevInput) - 1] != currInput[0]) {
printf("First letter of word does not match last letter of previous word\n");
exit(1);
}
if (!isValidWord(currInput, dict, &board, dictNum, trackChar)) {
freeMemory(dict, dictNum);
exit(0);
}
strcpy(prevInput, currInput); // update previous input
}
for (int i = 0; i < board.numSides; i++) {
for (size_t j = 0; j < strlen(board.sides[i]); j++) {
if (!trackChar[board.sides[i][j] - 'a']) {
printf("Not all letters used\n");
exit(0);
}
}
}
printf("Correct\n");
freeMemory(dict, dictNum);
return 0;
}
void loadBoard(const char *fileName, Board *board) {
FILE *file = fopen(fileName, "r");
if (!file) {
printf("Board file invalid\n");
exit(1);
}
int trackCharNum[26] = {0};
board->numSides = 0;
// read each side(line) from file and store in the board side array
while (fgets(board->sides[board->numSides], MAX_ALPHABET + 1, file) != NULL) {
board->sides[board->numSides][strcspn(board->sides[board->numSides], "\n")] = 0; // remove newline
for (size_t i = 0; i < strlen(board->sides[board->numSides]); i++) {
int charIndex = board->sides[board->numSides][i] - 'a';
if (trackCharNum[charIndex] > 0) {
printf("Invalid board\n"); // board contains a letter more than once
exit(1);
}
trackCharNum[charIndex]++;
}
board->numSides++; // next side(line) of the board
}
if (board->numSides < 3) {
printf("Invalid board\n");
exit(1);
}
fclose(file);
}
char **loadDict(const char *fileName, int *num) {
FILE *file = fopen(fileName, "r");
if (!file) {
printf("Dictionary file invalid\n");
exit(1);
}
int dictSize = INITIAL_DICT_SIZE;
char **dict = malloc(dictSize * sizeof(char *));
if (!dict) {
printf("Memory allocation of dictionary array failed\n");
exit(1);
}
char word[MAX_WORD_SIZE];
while (fscanf(file, "%s", word) != EOF) {
if (*num >= dictSize) {
dictSize *= 2;
char **newDict = realloc(dict, dictSize * sizeof(char *)); // dynamically allocate memory
if (!newDict) {
freeMemory(dict, *num);
printf("Memory allocation failed\n");
exit(1);
}
dict = newDict;
}
dict[*num] = strdup(word); // assign word in the dictionary file to the dictionary array
if (!dict[*num]) {
freeMemory(dict, *num);
printf("Memory allocation failed\n");
exit(1);
}
(*num)++; // increment num after allocation
}
fclose(file);
return dict;
}
int isValidWord(const char *inputWord, char **dict, Board *board, int dictNum, int *trackChar) {
bool foundDict = false;
for (int i = 0; i < dictNum; i++) {
if (strcmp(inputWord, dict[i]) == 0) {
foundDict = true;
break;
}
}
if (!foundDict) {
printf("Word not found in dictionary\n");
return 0;
}
int prevSideNum = -1;
for (size_t i = 0; i < strlen(inputWord); i++) {
char currChar = inputWord[i]; // loop through each character of word
bool foundBoard = false;
for (int sideNum = 0; sideNum < board->numSides; sideNum++) {
if (strchr(board->sides[sideNum], currChar) != NULL) { // returns the index of char if found in board side
foundBoard = true;
if (prevSideNum == sideNum) {
printf("Same-side letter used consecutively\n");
return 0;
}
trackChar[currChar - 'a'] = 1;
prevSideNum = sideNum; // update previous side num to the board side num in which char exists
break; // break out of the loop since the char is found in the board
}
}
if (!foundBoard) {
printf("Used a letter not present on the board\n");
return 0;
}
}
return 1;
}
void freeMemory(char **dict, int dictNum) {
for (int i = 0; i < dictNum; i++) {
free(dict[i]);
}
free(dict);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment