day 6 part 2

main
magical 2024-12-06 05:49:05 +00:00
parent c40379371e
commit 67cd627138
2 changed files with 84 additions and 18 deletions

View File

@ -1,2 +1,2 @@
CFLAGS=-O2 -std=c99 -Wall -Wextra CFLAGS=-O2 -std=c99 -ggdb -Wall -Wextra
all: sol all: sol

View File

@ -1,4 +1,5 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <limits.h> #include <limits.h>
@ -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 { int x, y, dx, dy; bool ok; };
struct step_r step(struct grid *g, int x, int y, int dx, int dy) { struct step_r step(struct grid *g, int x, int y, int dx, int dy) {
int i;
struct step_r r = {0}; struct step_r r = {0};
if (!inbounds(g, x, y)) { if (!inbounds(g, x, y)) {
return r; return r;
@ -104,45 +104,111 @@ struct step_r step(struct grid *g, int x, int y, int dx, int dy) {
} }
} }
struct point { int x, y; };
int solve(struct grid *g) { struct point startingPoint(struct grid *g) {
int x, y; int x, y;
int cx = -1, cy = -1;
int count = 0;
for (y = 0; y < g->y; y++) for (y = 0; y < g->y; y++)
for (x = 0; x < g->x; x++) { for (x = 0; x < g->x; x++) {
if (g->A[y][x] == '^') { if (g->A[y][x] == '^') {
cx = x; struct point r = {x, y};
cy = y; return r;
break;
} }
} }
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 int dx = 0, dy = -1; // up
while(inbounds(g, cx, cy)) { while(inbounds(g, x, y)) {
if (g->A[cy][cx] != 'x') { if (g->A[y][x] != 'x') {
count++; 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) { if (r.ok != true) {
break; break;
} }
cx = r.x; x = r.x;
cy = r.y; y = r.y;
dx = r.dx; dx = r.dx;
dy = r.dy; dy = r.dy;
} }
g->A[start.y][start.x] = '^';
printf("%d\n", count); printf("%d\n", count);
return 0; 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() { int main() {
struct grid g; struct grid g;
readfile("sample1.in", &g); //readfile("sample1.in", &g);
readfile("input", &g); readfile("input", &g);
printf("%d %d\n", g.x, g.y); printf("%d %d\n", g.x, g.y);
solve(&g); solve(&g);
//solve2(&g); //printf("%s", g.A[0]);
printf("%s", g.A[0]); solve2(&g);
} }