#include #include #include #include #include #define DEFAULT_FILE "input2.txt" #define STRBUF_LEN 200 #define GRID_ROWS 5 #define GRID_COLS 5 /********************************************************/ // Linked List Functions /********************************************************/ // Node structure typedef struct ll_node { void *data; struct ll_node *next; } ll_node; // Linked list structure typedef struct linked_list { ll_node* head; } linked_list; void ll_init(linked_list* list) { list->head = NULL; } // Function to create a new node ll_node* ll_create_node(void *data) { ll_node* new_node = (ll_node*)malloc(sizeof(ll_node)); if (new_node != NULL) { new_node->data = data; new_node->next = NULL; } return new_node; } // Function to add a node to the beginning of the list void ll_prepend(linked_list* list, void *data) { ll_node* new_node = ll_create_node(data); if (new_node != NULL) { new_node->next = list->head; list->head = new_node; } } // Function to add a node to the end of the list void ll_append(linked_list* list, void *data) { ll_node* newNode = ll_create_node(data); if (newNode != NULL) { if (list->head == NULL) { list->head = newNode; } else { ll_node* current = list->head; while (current->next != NULL) { current = current->next; } current->next = newNode; } } } // Function to remove a node with a given value void ll_remove(linked_list* list, void *data, bool (*compare_function)(void *, void*)) { ll_node* current = list->head; ll_node* prev = NULL; while (current != NULL && !compare_function(current->data, data)) { prev = current; current = current->next; } if (current != NULL) { if (prev != NULL) { prev->next = current->next; } else { list->head = current->next; } free(current); } } // Function to free the memory used by the linked list void ll_free(linked_list* list) { ll_node* current = list->head; ll_node* next; while (current != NULL) { next = current->next; free(current->data); free(current); current = next; } list->head = NULL; } uint64_t ll_len(linked_list* list) { uint64_t len = 0; ll_node *current = list->head; while (current != NULL) { len++; current = current->next; } return len; } /** * @brief Prints all elements in a linked list * * @param list * @param print_data_func A function that prints the data of a node when * passed the pointer to its data */ void print_list(linked_list *list, void (*print_data_func)(void *data)) { ll_node* current = list->head; while (current != NULL) { print_data_func(current->data); current = current->next; } } /********************************************************/ // Implimentation Specific Linked List Functions /********************************************************/ typedef struct _distance_data { int row; int col; int distance; } distance_data; void print_data_func(void *data) { distance_data *d = (distance_data *)data; int row = d->row; int col = d->col; int distance = d->distance; printf("R:%d C:%d D:%d\n", row, col, distance); } /********************************************************/ // Challenge functions /********************************************************/ /** * @brief Reads a file and loads the grid into * an array of rows and columns */ void load_grid(FILE *file, char grid[GRID_ROWS][GRID_COLS]) { char strbuf[STRBUF_LEN] = {0}; int i = 0; for (i = 0; i < GRID_ROWS; i++) { fgets(strbuf, STRBUF_LEN, file); memcpy(grid[i], strbuf, GRID_COLS); } } /** * @brief Finds the row and col idx of the 'S' char and places them in row_idx and col_idx * * @return true if S is found * @return false if S is not found */ bool find_s(char grid[GRID_ROWS][GRID_COLS], int *row_idx, int *col_idx) { int r; int c; for (r = 0; r < GRID_ROWS; r++) { for (c = 0; c < GRID_ROWS; c++) { if (grid[r][c] == 'S') { *row_idx = r; *col_idx = c; return true; } } } return false; } /** * @brief Populates a node on the linked list with information * about a single nodes distance value */ void append_distance(int distance, int row, int col, linked_list *list) { distance_data *data = malloc(sizeof(distance_data)); data->row = row; data->col = col; data->distance = distance; ll_append(list, data); } /** * @brief Checks if the cell above should be populated, and populates it if so * * @return true if the cell was populated * @return false if the cell was not populatd */ void populate_distance_above(distance_data *data, linked_list *list, char grid[GRID_ROWS][GRID_COLS]) { int row = data->row; int col = data->col; int distance = data->distance; if (!col) return; char above = grid[row][col - 1]; if (above != '|' && above != '7' && above != 'F') return; append_distance(distance + 1, row, col - 1, list); } /** * @brief Checks if the cell to the left should be populated, and populates it if so * * @return true if the cell was populated * @return false if the cell was not populatd */ void populate_distance_left(distance_data *data, linked_list *list, char grid[GRID_ROWS][GRID_COLS]) { int row = data->row; int col = data->col; int distance = data->distance; if (!row) return; char left = grid[row - 1][col]; if (left != '-' && left != 'L' && left != 'F') return; append_distance(distance + 1, row - 1, col, list); } /** * @brief Checks if the cell to the right should be populated, and populates it if so * * @return true if the cell was populated * @return false if the cell was not populatd */ void populate_distance_right(distance_data *data, linked_list *list, char grid[GRID_ROWS][GRID_COLS]) { int row = data->row; int col = data->col; int distance = data->distance; if (row == GRID_ROWS) return; char right = grid[row + 1][col]; if (right != '-' && right != '7' && right != 'J') return; append_distance(distance + 1, row + 1, col, list); } /** * @brief Checks if the cell below should be populated, and populates it if so * * @param data * @param list * @param grid * @return true if the cell was populated * @return false if the cell was not populatd */ bool populate_distance_below(distance_data *data, linked_list *list, char grid[GRID_ROWS][GRID_COLS]) { int row = data->row; int col = data->col; int distance = data->distance; if (col == GRID_COLS) return false; char below = grid[row][col + 1]; if (below != '|' && below != 'J' && below != 'L') return false; append_distance(distance + 1, row, col + 1, list); return true; } void populate_distances_around(distance_data *data, linked_list *list, char grid[GRID_ROWS][GRID_COLS]) { int r = data->row; int col = data->col; int distance = data->distance; populate_distance_above(data, list, grid); populate_distance_left(data, list, grid); populate_distance_right(data, list, grid); populate_distance_below(data, list, grid); } /** * @brief Traverses each node of a linked list and populates all distances around those nodes * * @param distance the NEW distance to populate */ void populate_distance_step(int distance, linked_list *list, char grid[GRID_ROWS][GRID_COLS]) { ll_node *current = list->head; while (current != NULL) { } } int main(int argc, char **argv) { // Get filename as an argument, if there is one char *path = (argc > 1) ? argv[1] : DEFAULT_FILE; if (!path) { printf("Requires input file.\n"); return 1; } FILE *file = fopen(path, "r"); if (!file) { printf("Could not find file."); return 1; } char grid[GRID_ROWS][GRID_COLS] = {0}; linked_list dist_list; ll_init(&dist_list); load_grid(file, grid); int r = 0; int c = 0; if (!find_s(grid, &r, &c)) { printf("Could not find S???\n"); return 1; } append_distance(0, r, c, &dist_list); printf("%c", grid[r][c]); return 0; }