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