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

View File

@ -1,4 +1,5 @@
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <string.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 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);
}