diff --git a/solution/letter-boxed.c b/solution/letter-boxed.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..ffc9a85c149d2f4fce7e7532f785c58e8de706c5 100644
--- a/solution/letter-boxed.c
+++ b/solution/letter-boxed.c
@@ -0,0 +1,187 @@
+#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);
+}