diff options
author | kartofen <mladenovnasko0@gmail.com> | 2023-12-07 22:53:58 +0200 |
---|---|---|
committer | kartofen <mladenovnasko0@gmail.com> | 2023-12-07 22:53:58 +0200 |
commit | e65e727889ec4b023669573797bc5ba1184347e7 (patch) | |
tree | 5470246d1ec380fc7e967372e2f0dce14d4062ed /Advent-of-Code-2023/aoc-3/main.c | |
parent | d846186789ace51fd9da839ce9ef0b1ce97956a3 (diff) |
Diffstat (limited to 'Advent-of-Code-2023/aoc-3/main.c')
-rw-r--r-- | Advent-of-Code-2023/aoc-3/main.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/Advent-of-Code-2023/aoc-3/main.c b/Advent-of-Code-2023/aoc-3/main.c new file mode 100644 index 0000000..2041f4d --- /dev/null +++ b/Advent-of-Code-2023/aoc-3/main.c @@ -0,0 +1,144 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include <stdint.h> + +// 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++; +} |