Day3 C
This commit is contained in:
155
day3/c/day3.c
Normal file
155
day3/c/day3.c
Normal file
@@ -0,0 +1,155 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
Reference in New Issue
Block a user