day 18
This commit is contained in:
parent
ea878a2067
commit
1cb6b9117e
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,159 @@
|
|||
#include "aoc.h"
|
||||
|
||||
typedef struct {
|
||||
i32 x, y;
|
||||
} Vec2i;
|
||||
|
||||
static Vec2i
|
||||
parse_vec2i(str line, Arena tmp) {
|
||||
str left, right;
|
||||
str_split(line, STR(","), &left, &right);
|
||||
Vec2i result = {
|
||||
.x = parse_i64(str_trim(left), tmp),
|
||||
.y = parse_i64(str_trim(right), tmp),
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
static Vec2i
|
||||
vec2i(i32 x, i32 y) {
|
||||
Vec2i result = { .x = x, .y = y };
|
||||
return result;
|
||||
}
|
||||
|
||||
static void
|
||||
simulate_falling(Vec2i *bytes, isize bytes_len, u8 *grid, i32 width, i32 height) {
|
||||
for (isize i = 0; i < bytes_len; i++) {
|
||||
Vec2i byte = bytes[i];
|
||||
grid[byte.y * width + byte.x] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dump_grid(u8 *grid, i32 width, i32 height) {
|
||||
for (i32 y = 0; y < height; y++) {
|
||||
for (i32 x = 0; x < width; x++) {
|
||||
u8 cell = grid[y * width + x];
|
||||
if (cell) {
|
||||
printf("#");
|
||||
} else {
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
Vec2i *points;
|
||||
i32 write, read;
|
||||
isize size;
|
||||
} Queue;
|
||||
|
||||
static inline i32
|
||||
queue_next(Queue *queue, i32 index) {
|
||||
return (index + 1) % queue->size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
queue_push(Queue *queue, Vec2i pos) {
|
||||
ASSERT(queue_next(queue, queue->write) != queue->read);
|
||||
queue->points[queue->write] = pos;
|
||||
queue->write = queue_next(queue, queue->write);
|
||||
}
|
||||
|
||||
static inline Vec2i
|
||||
queue_pop(Queue *queue) {
|
||||
ASSERT(queue->read != queue->write);
|
||||
Vec2i result = queue->points[queue->read];
|
||||
queue->read = queue_next(queue, queue->read);
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
queue_empty(Queue *queue) {
|
||||
return queue->write == queue->read;
|
||||
}
|
||||
|
||||
static i32
|
||||
solve(Arena temp, u8 *grid, i32 width, i32 height) {
|
||||
i32 end_x = width - 1, end_y = height - 1;
|
||||
i32 x = 0, y = 0;
|
||||
Queue queue = { .size = 1024 };
|
||||
queue.points = ARENA_ALLOC_ARRAY(&temp, Vec2i, queue.size);
|
||||
i32 *distance = ARENA_ALLOC_ARRAY(&temp, i32, width * height);
|
||||
for (i32 i = 0; i < width * height; i++) {
|
||||
distance[i] = INT32_MAX;
|
||||
}
|
||||
distance[y * width + x] = 0;
|
||||
queue_push(&queue, vec2i(x, y));
|
||||
static const Vec2i offsets[] = {
|
||||
{ .x = 0, .y = -1 },
|
||||
{ .x = 0, .y = 1 },
|
||||
{ .x = -1, .y = 0 },
|
||||
{ .x = 1, .y = 0 },
|
||||
};
|
||||
while (!queue_empty(&queue)) {
|
||||
Vec2i point = queue_pop(&queue);
|
||||
i32 dist = distance[point.y * width + point.x];
|
||||
ASSERT(dist < INT32_MAX);
|
||||
for (i32 i = 0; i < 4; i++) {
|
||||
Vec2i offset = offsets[i];
|
||||
i32 nx = point.x + offset.x;
|
||||
i32 ny = point.y + offset.y;
|
||||
if (nx >= 0 && ny >= 0 && nx < width && ny < height
|
||||
&& !grid[ny * width + nx]
|
||||
&& dist + 1 < distance[ny * width + nx])
|
||||
{
|
||||
distance[ny * width + nx] = dist + 1;
|
||||
queue_push(&queue, vec2i(nx, ny));
|
||||
}
|
||||
}
|
||||
}
|
||||
return distance[end_y * width + end_x];
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Arena *arena = make_arena(Megabytes(1));
|
||||
Tokens lines = read_lines(arena, argv[1]);
|
||||
|
||||
Vec2i *bytes = ARENA_ALLOC_ARRAY(arena, Vec2i, lines.len);
|
||||
bool is_test = true;
|
||||
for (isize i = 0; i < lines.len; i++) {
|
||||
bytes[i] = parse_vec2i(lines.tokens[i], *arena);
|
||||
if (bytes[i].x > 6 || bytes[i].y > 6) {
|
||||
is_test = false;
|
||||
}
|
||||
}
|
||||
|
||||
i32 width, height;
|
||||
i32 part_1_limit;
|
||||
if (is_test) {
|
||||
width = 7;
|
||||
height = 7;
|
||||
part_1_limit = 12;
|
||||
}
|
||||
else {
|
||||
width = 71;
|
||||
height = 71;
|
||||
part_1_limit = 1024;
|
||||
}
|
||||
u8 *grid = ARENA_ALLOC_ARRAY(arena, u8, width * height);
|
||||
|
||||
// part 1
|
||||
simulate_falling(bytes, part_1_limit, grid, width, height);
|
||||
/* dump_grid(grid, width, height); */
|
||||
i32 part_1 = solve(*arena, grid, width, height);
|
||||
printf("%d\n", part_1);
|
||||
|
||||
// part 2
|
||||
memset(grid, 0, width * height);
|
||||
for (isize cutoff = 0; cutoff < lines.len; cutoff++) {
|
||||
simulate_falling(bytes + cutoff, 1, grid, width, height);
|
||||
i32 result = solve(*arena, grid, width, height);
|
||||
if (result == INT32_MAX) {
|
||||
printf("%d,%d\n", bytes[cutoff].x, bytes[cutoff].y);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
5,4
|
||||
4,2
|
||||
4,5
|
||||
3,0
|
||||
2,1
|
||||
6,3
|
||||
2,4
|
||||
1,5
|
||||
0,6
|
||||
3,3
|
||||
2,6
|
||||
5,1
|
||||
1,2
|
||||
5,5
|
||||
2,5
|
||||
6,5
|
||||
1,4
|
||||
0,4
|
||||
6,4
|
||||
1,1
|
||||
6,1
|
||||
1,0
|
||||
0,5
|
||||
1,6
|
||||
2,0
|
||||
Loading…
Reference in New Issue