#include #include #include #define LINE_MAX_LENGTH 256 #define MAX_MAP_SIZE 1024 #define MAX_NUMBERS 32*1024 #define abs(a) ((a) < 0 ? -(a) : (a)) struct num_position_t { int x; int y; int length; unsigned int value; }; struct num_position_t* create_position(int x, int y, int length, unsigned int value); int has_adjacent_symbol(struct num_position_t* number, int symbol_map[MAX_MAP_SIZE][MAX_MAP_SIZE]); unsigned int gear_ratio(int x, int y, struct num_position_t** numbers, int num_numbers); int main() { char *p, *buf, c, tmp[64]; struct num_position_t **numbers, *tmp_pos; numbers = (struct num_position_t**)malloc(MAX_NUMBERS * sizeof(struct num_position_t*)); int symbol_map[MAX_MAP_SIZE][MAX_MAP_SIZE]; memset(symbol_map, 0, MAX_MAP_SIZE*MAX_MAP_SIZE*sizeof(int)); int num_numbers = 0, num_length = 0; unsigned int curr = 0; int x = 0, y = 0; buf = (char *)malloc(LINE_MAX_LENGTH); memset(buf, 0, LINE_MAX_LENGTH); p = buf; int map_x = 0; int map_y = 0; while ((c = getchar()) != EOF) { *p++ = c; if (c == '\n') { p = buf; while (*p != '\n') { if (*p == '-' || *p == '+') { symbol_map[x][y] = 1; p++; x++; } else if (sscanf(p, "%u", &curr) != 0) { num_length = sprintf(tmp, "%u", curr); tmp_pos = create_position(x, y, num_length, curr); numbers[num_numbers] = tmp_pos; num_numbers++; p += num_length; x += num_length; } else { if (*p != '.') { symbol_map[x][y] = 1; } if (*p == '*') { symbol_map[x][y] = 2; } p++; x++; } } map_x = x; x = 0; y++; memset(buf, 0, LINE_MAX_LENGTH); p = buf; } } map_y = y; // Part 1 unsigned int part1 = 0; for (int i = 0; i < num_numbers; i++) { if (has_adjacent_symbol(numbers[i], symbol_map)) { part1 += numbers[i]->value; } } printf("%u\n", part1); // Part 2 unsigned int part2 = 0; for (int i = 0; i < map_y; i++) { for (int j = 0; j < map_x; j++) { if (symbol_map[j][i] == 2) { part2 += gear_ratio(j, i, numbers, num_numbers); } } } printf("%u\n", part2); free(buf); for (int i = 0; i < num_numbers; i++) { free(numbers[i]); } free(numbers); } struct num_position_t* create_position(int x, int y, int length, unsigned int value) { struct num_position_t *pos; pos = (struct num_position_t*)malloc(sizeof(struct num_position_t)); pos->x = x; pos->y = y; pos->length = length; pos->value = value; return pos; } int has_adjacent_symbol(struct num_position_t* number, int symbol_map[MAX_MAP_SIZE][MAX_MAP_SIZE]) { int x, y; for (int i = 0; i < number->length; i++) { for (int j = -1; j <= 1; j++) { for (int k = -1; k <= 1; k++) { x = number->x + i + j; y = number->y + k; if (x < 0 || y < 0) continue; if (symbol_map[x][y]) return 1; } } } return 0; } unsigned int gear_ratio(int x, int y, struct num_position_t** numbers, int num_numbers) { int gear_num = 0; unsigned int num_parts[2]; for (int i = 0; i < num_numbers; i++) { for (int j = 0; j < numbers[i]->length; j++) { if (abs(numbers[i]->x + j - x) <= 1 && abs(numbers[i]->y - y) <= 1) { // Not a gear if (gear_num == 2) return 0; // Add gear num_parts[gear_num] = numbers[i]->value; gear_num++; break; } } } if (gear_num == 2) { return num_parts[0] * num_parts[1]; } return 0; }