// // Created by lennart on 12/6/23. // #include #include #include #include #include #include "input_handler.h" typedef struct { char **data; int height; int width; } PartsMap; // Functions PartsMap* load_map(const char *file_name); void free_map(PartsMap *map); bool is_adjacent_to_symbol(PartsMap *map, int row, int col, int len); bool is_gear(PartsMap *map, int g_row, int g_col, int *num1, int *num2); int main() { PartsMap *map = load_map("day_3.txt"); // Part 1 - Iterate over each row and find numbers with adjacent symbols int sum = 0; for(int row = 0; row < map->height; row++) { const char *begin = &map->data[row][0]; char *pos = (char*) begin; while(*pos != 0) { const char *before = pos; if(isdigit(*pos)) { unsigned long num = strtoul(before, &pos, 10); if(is_adjacent_to_symbol(map, row, (int) (before - begin), (int) (pos - before))) { sum += (int) num; } } else { pos++; } } } printf("Result #1: %i\n", sum); // Part 2 - Iterate over each row and find gear symbols (*) with 2 adjacent numbers sum = 0; for(int row = 0; row < map->height; row++) { for(int col = 0; col < map->width; col++) { if(map->data[row][col] == '*') { int num1, num2; if(is_gear(map, row, col, &num1, &num2)) { sum += num1 * num2; } } } } printf("Result #2: %i", sum); free_map(map); } bool is_gear(PartsMap *map, int g_row, int g_col, int *num1, int *num2) { int count = 0; int rowMin = max(g_row - 1, 0); int rowMax = min(g_row + 1, map->height - 1); int colMin = max(g_col - 1, 0); int colMax = min(g_col + 1, map->width - 1); for(int row = rowMin; row <= rowMax; row++) { const char *begin = &map->data[row][0]; char *pos = &map->data[row][colMin]; while(isdigit(*pos) && pos > begin) { pos--; } while(pos - begin <= colMax) { if(isdigit(*pos)) { const char *before = pos; unsigned long num = strtoul(before, &pos, 10); if(++count == 1) { *num1 = (int) num; } else if(count == 2) { *num2 = (int) num; } else { return false; // More than 2 adjacent numbers } } else { pos++; } } } return count == 2; } bool is_adjacent_to_symbol(PartsMap *map, int row, int col, int len) { int rowMin = max(row - 1, 0); int rowMax = min(row + 2, map->height); int colMin = max(col - 1, 0); int colMax = min(col + len + 1, map->width); for(int cr = rowMin; cr < rowMax; cr++) { for(int cc = colMin; cc < colMax; cc++) { char c = map->data[cr][cc]; if(c != '.' && !isdigit(c)) { return true; } } } return false; } PartsMap* load_map(const char *file_name) { FILE *f = fopen(file_name, "r"); if(f == NULL) { printf("ERROR: Input file not found!"); exit(1); } char *buffer = NULL; int bufferLen = 0; size_t length = 16; PartsMap *map = malloc(sizeof (PartsMap)); map->height = 0; map->data = malloc(sizeof (map->data) * length); while(!feof(f)) { if(map->height >= length) { map->data = realloc(map->data, sizeof (map->data) * (length *= 2)); } read_line(f, &buffer, &bufferLen); map->data[map->height++] = strdup(buffer); } map->width = strlen(map->data[0]); fclose(f); free(buffer); return map; } void free_map(PartsMap *map) { for(size_t row = 0; row < map->height; row++) { free(map->data[row]); } free(map->data); free(map); }