advent2023

Advent of Code 2023 solutions
git clone git://bsandro.tech/advent2023
Log | Files | Refs | LICENSE

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:
M.gitignore | 1+
Mday03/puzzle.c | 70+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
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; + } + } } } }