#include #include #include #include #include // too low 425996 // #define FILENAME "sample.txt" #define FILENAME "input.txt" #define BOARD_MAX 256 #define NUMBERS_MAX 2048 #define MIN(a,b) (((int)(a)<(int)(b))?(a):(b)) #define MAX(a,b) (((int)(a)>(int)(b))?(a):(b)) typedef struct { int number; size_t x; size_t y; size_t len; } num; typedef struct { size_t x; size_t y; uint64_t p; size_t nrefs; } gear; void num_print(num number); int num_near_symbol(num number); void gear_print(gear g); void gear_add(size_t x, size_t y, size_t number); static num numbers[NUMBERS_MAX]; static size_t nnumbers; static gear gears[NUMBERS_MAX]; static size_t ngears; static char board[BOARD_MAX][BOARD_MAX]; static size_t width; static size_t height; int main(void) { FILE *fp = fopen(FILENAME, "r"); if(!fp) { perror("fopen: failed"); return 1; } char line[256]; fgets(line, sizeof(line), fp); width = strlen(line) - 1; // minus \n fseek(fp, 0, SEEK_SET); // load the numbers while(fgets(line, sizeof(line), fp)) { // copy the board memcpy(board[height], line, width); char numstr[16] = {0}; size_t len = 0; for(size_t i = 0; i < width; i++) { while(isdigit(board[height][i])){ numstr[len] = board[height][i]; i++; len++; } if(numstr[0] != 0) { numbers[nnumbers++] = (num){ atoi(numstr), i-len, height, len }; memset(numstr, 0, sizeof(numstr)); len = 0; } } height++; } fclose(fp); uint64_t sum = 0; for(size_t i = 0; i < nnumbers; i++) { if(num_near_symbol(numbers[i])) { sum += numbers[i].number; } } printf("Part 1: %lu\n", sum); sum = 0; for(size_t i = 0; i < ngears; i++) { if(gears[i].nrefs == 2) sum += gears[i].p; } printf("Part 2: %lu\n", sum); return 0; } int num_near_symbol(num number) { for(size_t i = MAX(number.y - 1, 0); i <= MIN(number.y + 1, height-1); i++) for(size_t j = MAX(number.x - 1, 0); j <= MIN(number.x + number.len, width-1); j++) { if((i == number.y) && ((j >= number.x) && (j < number.x + number.len))) continue; if(board[i][j] == '*') gear_add(j, i, number.number); if(board[i][j] != '.') return 1; } return 0; } void num_print(num number) { printf("%d: %ld %ld %ld\n", number.number, number.len, number.x, number.y); } void gear_print(gear g) { printf("%ld %ld %ld %ld\n", g.x, g.y, g.nrefs, g.p); } void gear_add(size_t x, size_t y, size_t number) { for(size_t i = ngears - 1; i < ngears; i--) if((gears[i].x == x) && (gears[i].y == y)) { gears[i].nrefs++; gears[i].p *= number; return; } gears[ngears].x = x; gears[ngears].y = y; gears[ngears].p = number; gears[ngears].nrefs = 1; ngears++; }