day 6 part 2
parent
c40379371e
commit
67cd627138
|
@ -1,2 +1,2 @@
|
|||
CFLAGS=-O2 -std=c99 -Wall -Wextra
|
||||
CFLAGS=-O2 -std=c99 -ggdb -Wall -Wextra
|
||||
all: sol
|
||||
|
|
100
day06/sol.c
100
day06/sol.c
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue