From 67cd62713851b1b671872365fbcf62e059ba02ef Mon Sep 17 00:00:00 2001 From: Andrew Ekstedt Date: Fri, 6 Dec 2024 05:49:05 +0000 Subject: [PATCH] day 6 part 2 --- day06/Makefile | 2 +- day06/sol.c | 100 ++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 84 insertions(+), 18 deletions(-) diff --git a/day06/Makefile b/day06/Makefile index 8b7b9d4..2fc7e6e 100644 --- a/day06/Makefile +++ b/day06/Makefile @@ -1,2 +1,2 @@ -CFLAGS=-O2 -std=c99 -Wall -Wextra +CFLAGS=-O2 -std=c99 -ggdb -Wall -Wextra all: sol diff --git a/day06/sol.c b/day06/sol.c index f93268f..f5fc423 100644 --- a/day06/sol.c +++ b/day06/sol.c @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -80,7 +81,6 @@ inline bool inbounds(struct grid *g, int x, int y) { struct step_r { int x, y, dx, dy; bool ok; }; struct step_r step(struct grid *g, int x, int y, int dx, int dy) { - int i; struct step_r r = {0}; if (!inbounds(g, x, y)) { return r; @@ -104,45 +104,111 @@ struct step_r step(struct grid *g, int x, int y, int dx, int dy) { } } - -int solve(struct grid *g) { +struct point { int x, y; }; +struct point startingPoint(struct grid *g) { int x, y; - int cx = -1, cy = -1; - int count = 0; for (y = 0; y < g->y; y++) for (x = 0; x < g->x; x++) { if (g->A[y][x] == '^') { - cx = x; - cy = y; - break; + struct point r = {x, y}; + return r; } } + struct point r = {-1,-1}; + return r; +} + +int solve(struct grid *g) { + struct point start = startingPoint(g); + int x = start.x, y = start.y; + int count = 0; int dx = 0, dy = -1; // up - while(inbounds(g, cx, cy)) { - if (g->A[cy][cx] != 'x') { + while(inbounds(g, x, y)) { + if (g->A[y][x] != 'x') { count++; } - g->A[cy][cx] = 'x'; + g->A[y][x] = 'x'; - struct step_r r = step(g, cx, cy, dx, dy); + struct step_r r = step(g, x, y, dx, dy); if (r.ok != true) { break; } - cx = r.x; - cy = r.y; + x = r.x; + y = r.y; dx = r.dx; dy = r.dy; } + g->A[start.y][start.x] = '^'; printf("%d\n", count); return 0; } +// returns whether the chosen grid will cause the guard to get stuck in a loop +bool loops(struct grid *g, struct point start, uint16_t* state) { + int x = start.x; + int y = start.y; + int dx = 0, dy = -1; // up + int stride = g->x; + //printf("loops(%d,%d)\n", x,y); + while(inbounds(g, x, y)) { + uint16_t dir = 15; + if (dx == 1) { dir = 1; } + else if (dx == -1) { dir = 2; } + else if (dy == 1) { dir = 4; } + else if (dy == -1) { dir = 8; } + + uint16_t *s = &state[y*stride + x]; + if ((*s & dir) != 0) { + // revisited a state, loop! + return true; + } + *s |= dir; + + struct step_r r = step(g, x, y, dx, dy); + if (r.ok != true) { + // step failed, no loop + return false; + } + x = r.x; + y = r.y; + dx = r.dx; + dy = r.dy; + } + // left the map, no loop + return false; +} + + +int solve2(struct grid *g) { + int count = 0; + int ox, oy; // obstacle coords + struct point p = startingPoint(g); + size_t state_size = g->x * g->y * sizeof(uint16_t); + uint16_t *state = xrealloc(NULL, state_size); + for (oy = 0; oy < g->y; oy++) + for (ox = 0; ox < g->x; ox++) { + int c = g->A[oy][ox]; + if (c != '#' && c != '^') { + g->A[oy][ox] = '#'; + memset(state, 0, state_size); + if (loops(g, p, state)) { + count++; + } + g->A[oy][ox] = c; + } + } + free(state); + printf("%d\n", count); + return 0; +} + + int main() { struct grid g; - readfile("sample1.in", &g); + //readfile("sample1.in", &g); readfile("input", &g); printf("%d %d\n", g.x, g.y); solve(&g); - //solve2(&g); - printf("%s", g.A[0]); + //printf("%s", g.A[0]); + solve2(&g); }