commit 18d1e368688d5515276ce16a2e526d73563116c0
parent 1094963efd3db16c43de4349b1ef3c1514e60f64
Author: bsandro <email@bsandro.tech>
Date: Sun, 3 Dec 2023 17:53:32 +0200
day 03 p2 aka "nothing beats good old linked lists"
Diffstat:
2 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1 +1,2 @@
*.o
+*.swp
diff --git a/day03/puzzle.c b/day03/puzzle.c
@@ -11,13 +11,39 @@
#define STR_LEN 2048
// 140x140 for real one
-#define FIELD_SIZE 10
-//#define FIELD_SIZE 140
+//#define FIELD_SIZE 10
+#define FIELD_SIZE 140
bool is_digit(char b) {
return b>='0' && b<='9';
}
+typedef struct Gear {
+ int pos; // y * FIELD_SIZE + x
+ int part;
+ struct Gear *next;
+} Gear;
+
+Gear * find_gear(Gear *gears, int pos) {
+ Gear *gear = gears;
+ while (gear != NULL) {
+ if (gear->pos == pos) {
+ return gear;
+ }
+ gear = gear->next;
+ }
+ return NULL;
+}
+
+Gear * make_gear(Gear *prev) {
+ Gear *gear = malloc(sizeof(Gear));
+ memset(gear, 0, sizeof(Gear));
+ if (prev!=NULL) {
+ prev->next = gear;
+ }
+ return gear;
+}
+
bool check_part(int x, int y, const char (*field)[FIELD_SIZE][FIELD_SIZE]) {
for (int dy=-1; dy<=1; ++dy) {
for (int dx=-1; dx<=1; ++dx) {
@@ -33,6 +59,21 @@ bool check_part(int x, int y, const char (*field)[FIELD_SIZE][FIELD_SIZE]) {
return false;
}
+int check_gear(int x, int y, const char (*field)[FIELD_SIZE][FIELD_SIZE]) {
+ for (int dy=-1; dy<=1; ++dy) {
+ for (int dx=-1; dx<=1; ++dx) {
+ int dy1=y+dy;
+ int dx1=x+dx;
+ if (dy1>=0 && dy1<FIELD_SIZE && dx1>=0 && dx1<FIELD_SIZE) {
+ if ((*field)[dy1][dx1]=='*') {
+ return dy1*FIELD_SIZE+dx1;
+ }
+ }
+ }
+ }
+ return -1;
+}
+
void puzzle(const char *filename, long long *result1, long long *result2) {
FILE *infile = fopen(filename, "r");
if (infile == NULL) {
@@ -58,20 +99,43 @@ void puzzle(const char *filename, long long *result1, long long *result2) {
// mutiny! ignoring feof/ferror.
fclose(infile);
+ Gear *gears = NULL;
+ Gear *gear_last = NULL;
+
for (int y=0; y<FIELD_SIZE; ++y) {
int x = 0;
while (x<FIELD_SIZE) {
int digit = 0;
bool is_part = false;
+ int gear_pos = -1;
while (is_digit(field[y][x++])) {
int cx = x-1;
if (cx>=FIELD_SIZE) break; // too lazy to make it sane
- if (!is_part) is_part = check_part(cx, y, &field);
+ if (check_part(cx, y, &field)) is_part = true;
digit = digit*10 + field[y][cx] - '0';
+ if (gear_pos==-1) gear_pos = check_gear(cx, y, &field);
}
if (digit>0 && is_part) {
//printf("%d\n", digit);
*result1 += digit;
+
+ if (gear_pos != -1) {
+ Gear *gear = find_gear(gears, gear_pos);
+ if (gear!=NULL) {
+ *result2 += digit * gear->part;
+ gear->part = digit;
+ } else {
+ gear = make_gear(gear_last);
+ gear->pos = gear_pos;
+ gear->part = digit;
+ if (gears==NULL) gears = gear;
+
+ if (gear_last!=NULL) {
+ gear_last->next = gear;
+ }
+ gear_last = gear;
+ }
+ }
}
}
}