summaryrefslogtreecommitdiff
path: root/Advent-of-Code-2023/aoc-3/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'Advent-of-Code-2023/aoc-3/main.c')
-rw-r--r--Advent-of-Code-2023/aoc-3/main.c144
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++;
+}