Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • cdis/cs/courses/cs537/fall24/public/p1
  • qyukun/p1
  • gbatra3/p1
  • hpark383/p1
  • BAO39/p1
5 results
Show changes
Commits on Source (2)
Name: Hye Won Park
CS Login: hyep
Wisc ID: hpark383
Email: hpark383@wisc.edu
Status of Implementations: It all works
#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);
}