Compare commits
2 Commits
98c579c96f
...
fdfe0281d4
Author | SHA1 | Date | |
---|---|---|---|
fdfe0281d4 | |||
ffaa6955fb |
2
day22.c
2
day22.c
@ -574,6 +574,7 @@ static void assert_face_table_is_correct()
|
||||
|
||||
static void day22_part2(void *p)
|
||||
{
|
||||
/*
|
||||
assert_face_table_is_correct();
|
||||
|
||||
day22_data *data = (day22_data*)p;
|
||||
@ -590,6 +591,7 @@ static void day22_part2(void *p)
|
||||
|
||||
vec2 pos = start;
|
||||
day22_facing dir = FACING_RIGHT;
|
||||
*/
|
||||
// day22_follow_instructions(&cube_map, insts, &pos, &dir, (step_cb)day22_cube_step);
|
||||
|
||||
// u32 answer = (pos.y+1) * 1000 + (pos.x+1) * 4 + dir;
|
||||
|
309
day23.c
Normal file
309
day23.c
Normal file
@ -0,0 +1,309 @@
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "types.h"
|
||||
#include "vec2.h"
|
||||
#include "aoc.h"
|
||||
|
||||
#define CHUNK_BITS 4
|
||||
#define CHUNK_SIZE (1 << CHUNK_BITS)
|
||||
|
||||
typedef struct {
|
||||
vec2 *elves;
|
||||
u32 count;
|
||||
} day23_data;
|
||||
|
||||
typedef bool day23_chunk[CHUNK_SIZE * CHUNK_SIZE];
|
||||
|
||||
typedef struct {
|
||||
day23_chunk *chunks;
|
||||
i32 ox, oy;
|
||||
i32 width, height;
|
||||
} day23_world;
|
||||
|
||||
static void* day23_parse(char** lines, int line_count)
|
||||
{
|
||||
day23_data *data = malloc(sizeof(day23_data));
|
||||
data->count = 0;
|
||||
|
||||
for (int y = 0; y < line_count; y++) {
|
||||
for (int x = 0; x < strlen(lines[y]); x++) {
|
||||
data->count += (lines[y][x] == '#');
|
||||
}
|
||||
}
|
||||
|
||||
data->elves = malloc(sizeof(vec2) * data->count);
|
||||
|
||||
int i = 0;
|
||||
for (int y = 0; y < line_count; y++) {
|
||||
for (int x = 0; x < strlen(lines[y]); x++) {
|
||||
if (lines[y][x] == '#') {
|
||||
data->elves[i].x = x;
|
||||
data->elves[i].y = y;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void day23_world_init(day23_world *world, u32 width, u32 height)
|
||||
{
|
||||
world->ox = 0;
|
||||
world->oy = 0;
|
||||
world->width = width / CHUNK_SIZE + 1;
|
||||
world->height = height / CHUNK_SIZE + 1;
|
||||
world->chunks = calloc(world->width * world->height, sizeof(day23_chunk));
|
||||
}
|
||||
|
||||
static bool day23_is_between(i32 value, i32 min, i32 max)
|
||||
{
|
||||
return min <= value && value <= max;
|
||||
}
|
||||
|
||||
static vec2 day23_get_chunk_pos(day23_world *world, i32 x, i32 y)
|
||||
{
|
||||
vec2 chunk_pos = {
|
||||
.x = (x >> CHUNK_BITS) - world->ox,
|
||||
.y = (y >> CHUNK_BITS) - world->oy
|
||||
};
|
||||
return chunk_pos;
|
||||
}
|
||||
|
||||
static day23_chunk *day23_get_chunk(day23_world *world, i32 x, i32 y)
|
||||
{
|
||||
vec2 chunk_pos = day23_get_chunk_pos(world, x, y);
|
||||
i32 chunk_x = chunk_pos.x;
|
||||
i32 chunk_y = chunk_pos.y;
|
||||
|
||||
if (day23_is_between(chunk_x, 0, world->width-1) && day23_is_between(chunk_y, 0, world->height-1)) {
|
||||
u32 idx = chunk_y * world->width + chunk_x;
|
||||
return &world->chunks[idx];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static u32 day23_get_tile_offset_idx(day23_world *world, i32 x, i32 y)
|
||||
{
|
||||
// u32 mask = (1 << CHUNK_BITS) - 1;
|
||||
u32 chunk_x = (x + CHUNK_SIZE) % CHUNK_SIZE;
|
||||
u32 chunk_y = (y + CHUNK_SIZE) % CHUNK_SIZE;
|
||||
return chunk_y * CHUNK_SIZE + chunk_x;
|
||||
}
|
||||
|
||||
static void day23_world_set(day23_world *world, i32 x, i32 y, bool value)
|
||||
{
|
||||
day23_chunk *chunk = day23_get_chunk(world, x, y);
|
||||
if (chunk == NULL) {
|
||||
i32 chunk_x = x >> CHUNK_BITS;
|
||||
i32 chunk_y = y >> CHUNK_BITS;
|
||||
|
||||
i32 min_x = MIN(chunk_x, world->ox);
|
||||
i32 max_x = MAX(chunk_x, world->ox + (i32)world->width - 1);
|
||||
i32 min_y = MIN(chunk_y, world->oy);
|
||||
i32 max_y = MAX(chunk_y, world->oy + (i32)world->height - 1);
|
||||
|
||||
i32 new_width = max_x - min_x + 1;
|
||||
i32 new_height = max_y - min_y + 1;
|
||||
|
||||
i32 ox = abs(min_x - world->ox);
|
||||
i32 oy = abs(min_y - world->oy);
|
||||
|
||||
day23_chunk *new_chunks = calloc(new_height * new_width, sizeof(day23_chunk));
|
||||
for (int y = 0; y < world->height; y++) {
|
||||
for (int x = 0; x < world->width; x++) {
|
||||
u32 from_idx = y * world->width + x;
|
||||
u32 to_idx = (y + oy) * new_width + (x + ox);
|
||||
memcpy(new_chunks[to_idx], world->chunks[from_idx], sizeof(day23_chunk));
|
||||
}
|
||||
}
|
||||
|
||||
free(world->chunks);
|
||||
world->ox = min_x;
|
||||
world->oy = min_y;
|
||||
world->width = new_width;
|
||||
world->height = new_height;
|
||||
world->chunks = new_chunks;
|
||||
|
||||
chunk = day23_get_chunk(world, x, y);
|
||||
}
|
||||
|
||||
u32 tile_idx = day23_get_tile_offset_idx(world, x, y);
|
||||
(*chunk)[tile_idx] = value;
|
||||
}
|
||||
|
||||
static bool day23_world_get(day23_world *world, i32 x, i32 y)
|
||||
{
|
||||
day23_chunk *chunk = day23_get_chunk(world, x, y);
|
||||
if (chunk == NULL) return false;
|
||||
|
||||
u32 tile_idx = day23_get_tile_offset_idx(world, x, y);
|
||||
return (*chunk)[tile_idx];
|
||||
}
|
||||
|
||||
static void day23_world_print(day23_world *world)
|
||||
{
|
||||
for (int y = 0; y < world->height * CHUNK_SIZE; y++) {
|
||||
for (int x = 0; x < (world->width * CHUNK_SIZE); x++) {
|
||||
bool value = day23_world_get(world, x + world->ox * CHUNK_SIZE, y + world->oy * CHUNK_SIZE);
|
||||
printf(value ? "#" : ".");
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static bool day23_are_tiles_empty(day23_world *world, vec2 *pos, vec2 *offsets, u32 offset_count)
|
||||
{
|
||||
for (int i = 0; i < offset_count; i++) {
|
||||
if (day23_world_get(world, pos->x + offsets[i].x, pos->y + offsets[i].y)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool day23_are_neighours_empty(day23_world *world, vec2 *pos)
|
||||
{
|
||||
vec2 neighbours[] = {
|
||||
VEC2(-1, -1), VEC2( 0, -1), VEC2( 1, -1),
|
||||
VEC2(-1, 0) , VEC2( 1, 0),
|
||||
VEC2(-1, 1), VEC2( 0, 1), VEC2( 1, 1),
|
||||
};
|
||||
|
||||
return day23_are_tiles_empty(world, pos, neighbours, ARRAY_LEN(neighbours));
|
||||
}
|
||||
|
||||
static vec2 day23_propose(day23_world *world, vec2 *elf, u32 step_idx)
|
||||
{
|
||||
// NOTE: The second second position in each direction MUST be the middle one.
|
||||
vec2 check_positions[4][3] = {
|
||||
[0] = { VEC2(-1, -1), VEC2( 0, -1), VEC2( 1, -1) }, // North
|
||||
[1] = { VEC2(-1, 1), VEC2( 0, 1), VEC2( 1, 1) }, // South
|
||||
[2] = { VEC2(-1, -1), VEC2(-1, 0), VEC2(-1, 1) }, // West
|
||||
[3] = { VEC2( 1, -1), VEC2( 1, 0), VEC2( 1, 1) } // East
|
||||
};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
vec2 *offsets = check_positions[(step_idx + i) % 4];
|
||||
if (day23_are_tiles_empty(world, elf, offsets, ARRAY_LEN(check_positions[0]))) {
|
||||
vec2 proposed = VEC2(elf->x + offsets[1].x, elf->y + offsets[1].y);
|
||||
return proposed;
|
||||
}
|
||||
}
|
||||
|
||||
return *elf;
|
||||
}
|
||||
|
||||
static bool day23_step(day23_world *world, vec2 *elves, u32 elves_count, u32 step_idx)
|
||||
{
|
||||
bool no_moves = true;
|
||||
|
||||
vec2 proposed_positions[elves_count];
|
||||
for (int i = 0; i < elves_count; i++) {
|
||||
if (day23_are_neighours_empty(world, &elves[i])) {
|
||||
proposed_positions[i] = elves[i];
|
||||
} else {
|
||||
proposed_positions[i] = day23_propose(world, &elves[i], step_idx);
|
||||
no_moves = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool overlapping[elves_count];
|
||||
memset(overlapping, false, sizeof(bool) * elves_count);
|
||||
|
||||
for (int i = 0; i < elves_count - 1; i++) {
|
||||
for (int j = i + 1; j < elves_count; j++) {
|
||||
vec2 *pos1 = &proposed_positions[i];
|
||||
vec2 *pos2 = &proposed_positions[j];
|
||||
if (pos1->x == pos2->x && pos1->y == pos2->y) {
|
||||
overlapping[i] = true;
|
||||
overlapping[j] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < elves_count; i++) {
|
||||
if (overlapping[i]) continue;
|
||||
day23_world_set(world, elves[i].x, elves[i].y, false);
|
||||
day23_world_set(world, proposed_positions[i].x, proposed_positions[i].y, true);
|
||||
elves[i] = proposed_positions[i];
|
||||
}
|
||||
|
||||
return no_moves;
|
||||
}
|
||||
|
||||
static void day23_setup_world(day23_world *world, vec2 *elves, u32 count)
|
||||
{
|
||||
u32 initial_width = 0;
|
||||
u32 initial_height = 0;
|
||||
for (int i = 0; i < count; i++) {
|
||||
initial_width = MAX(elves[i].x+1, initial_width);
|
||||
initial_height = MAX(elves[i].y+1, initial_height);
|
||||
elves[i] = elves[i];
|
||||
}
|
||||
|
||||
day23_world_init(world, initial_width, initial_height);
|
||||
for (int i = 0; i < count; i++) {
|
||||
day23_world_set(world, elves[i].x, elves[i].y, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void day23_part1(void *p)
|
||||
{
|
||||
day23_data *data = (day23_data*)p;
|
||||
|
||||
vec2 elves[data->count];
|
||||
memcpy(elves, data->elves, sizeof(vec2) * data->count);
|
||||
|
||||
day23_world world;
|
||||
day23_setup_world(&world, data->elves, data->count);
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
day23_step(&world, elves, data->count, i);
|
||||
}
|
||||
|
||||
i32 min_x = elves[0].x;
|
||||
i32 min_y = elves[0].y;
|
||||
i32 max_x = elves[0].x;
|
||||
i32 max_y = elves[0].y;
|
||||
for (int i = 1; i < data->count; i++) {
|
||||
min_x = MIN(min_x, elves[i].x);
|
||||
min_y = MIN(min_y, elves[i].y);
|
||||
max_x = MAX(max_x, elves[i].x);
|
||||
max_y = MAX(max_y, elves[i].y);
|
||||
}
|
||||
|
||||
u32 answer = 0;
|
||||
for (int y = min_y; y <= max_y; y++) {
|
||||
for (int x = min_x; x <= max_x; x++) {
|
||||
answer += !day23_world_get(&world, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
printf("%d\n", answer);
|
||||
}
|
||||
|
||||
static void day23_part2(void *p)
|
||||
{
|
||||
day23_data *data = (day23_data*)p;
|
||||
|
||||
vec2 elves[data->count];
|
||||
memcpy(elves, data->elves, sizeof(vec2) * data->count);
|
||||
|
||||
day23_world world;
|
||||
day23_setup_world(&world, data->elves, data->count);
|
||||
|
||||
u32 steps = 0;
|
||||
while (true) {
|
||||
bool no_moves = day23_step(&world, elves, data->count, steps);
|
||||
steps++;
|
||||
if (no_moves) break;
|
||||
}
|
||||
|
||||
printf("%d\n", steps);
|
||||
}
|
||||
|
||||
ADD_SOLUTION(23, day23_parse, day23_part1, day23_part2);
|
310
day24.c
Normal file
310
day24.c
Normal file
@ -0,0 +1,310 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "vec2.h"
|
||||
#include "aoc.h"
|
||||
|
||||
#define DAY24_QUEUE_CAPACITY (1024 * 256)
|
||||
|
||||
typedef enum {
|
||||
DIR24_UP,
|
||||
DIR24_DOWN,
|
||||
DIR24_LEFT,
|
||||
DIR24_RIGHT,
|
||||
} day24_direction;
|
||||
char g_day24_direction[] = {
|
||||
[DIR24_UP ] = '^',
|
||||
[DIR24_DOWN ] = 'v',
|
||||
[DIR24_LEFT ] = '<',
|
||||
[DIR24_RIGHT] = '>'
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
vec2 pos;
|
||||
day24_direction direction;
|
||||
} day24_blizzard;
|
||||
|
||||
typedef struct {
|
||||
day24_blizzard *blizzards;
|
||||
u32 blizzard_count;
|
||||
u32 width;
|
||||
u32 height;
|
||||
} day24_data;
|
||||
|
||||
typedef struct {
|
||||
i8 x[DAY24_QUEUE_CAPACITY];
|
||||
i8 y[DAY24_QUEUE_CAPACITY];
|
||||
u16 time[DAY24_QUEUE_CAPACITY];
|
||||
|
||||
i32 front;
|
||||
i32 rear;
|
||||
} day24_queue;
|
||||
|
||||
static day24_direction day24_parse_direction(char symbol)
|
||||
{
|
||||
switch(symbol) {
|
||||
case '>': return DIR24_RIGHT;
|
||||
case '<': return DIR24_LEFT;
|
||||
case 'v': return DIR24_DOWN;
|
||||
case '^': return DIR24_UP;
|
||||
default: assert(false && "Invalid direction symbol");
|
||||
}
|
||||
}
|
||||
|
||||
static void* day24_parse(char** lines, int line_count)
|
||||
{
|
||||
day24_data *data = malloc(sizeof(day24_data));
|
||||
data->width = strlen(lines[0]);
|
||||
data->height = line_count;
|
||||
data->blizzards = malloc(data->width * data->height * sizeof(day24_blizzard));
|
||||
data->blizzard_count = 0;
|
||||
|
||||
for (int y = 1; y < data->height-1; y++) {
|
||||
for (int x = 1; x < data->width-1; x++) {
|
||||
char symbol = lines[y][x];
|
||||
if (symbol == '.') continue;
|
||||
size_t blizzard_idx = data->blizzard_count;
|
||||
|
||||
data->blizzards[blizzard_idx].pos.x = x;
|
||||
data->blizzards[blizzard_idx].pos.y = y;
|
||||
data->blizzards[blizzard_idx].direction = day24_parse_direction(symbol);
|
||||
data->blizzard_count++;
|
||||
}
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
static void day24_step(u16 *from_map, u16 *to_map, u32 width, u32 height, day24_blizzard *blizzards, u32 blizzard_count)
|
||||
{
|
||||
memcpy(to_map, from_map, sizeof(u16) * width * height);
|
||||
|
||||
for (int i = 0; i < blizzard_count; i++) {
|
||||
day24_blizzard *blizz = &blizzards[i];
|
||||
vec2 *pos = &blizz->pos;
|
||||
|
||||
to_map[pos->y * width + pos->x]--;
|
||||
|
||||
if (blizz->direction == DIR24_UP) {
|
||||
pos->y--;
|
||||
if (pos->y == 0) {
|
||||
pos->y = height-2;
|
||||
}
|
||||
} else if (blizz->direction == DIR24_DOWN) {
|
||||
pos->y++;
|
||||
if (pos->y == height-1) {
|
||||
pos->y = 1;
|
||||
}
|
||||
} else if (blizz->direction == DIR24_LEFT) {
|
||||
pos->x--;
|
||||
if (pos->x == 0) {
|
||||
pos->x = width-2;
|
||||
}
|
||||
} else { // if (blizz->direction == DIR24_RIGHT) {
|
||||
pos->x++;
|
||||
if (pos->x == width-1) {
|
||||
pos->x = 1;
|
||||
}
|
||||
}
|
||||
|
||||
to_map[pos->y * width + pos->x]++;
|
||||
}
|
||||
}
|
||||
|
||||
static day24_blizzard *day24_get_blizzard_at(day24_blizzard *blizzards, u32 count, i32 x, i32 y)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (blizzards[i].pos.x == x && blizzards[i].pos.y == y) {
|
||||
return &blizzards[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void day24_map_print(u16 *map, u32 width, u32 height)
|
||||
{
|
||||
printf("#.");
|
||||
for (int x = 2; x < width; x++) {
|
||||
printf("#");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
for (int y = 1; y < height-1; y++) {
|
||||
printf("#");
|
||||
for (int x = 1; x < width-1; x++) {
|
||||
u32 idx = y * width + x;
|
||||
if (map[idx] == 0) {
|
||||
printf(".");
|
||||
} else {
|
||||
printf("%d", map[idx]);
|
||||
}
|
||||
}
|
||||
printf("#\n");
|
||||
}
|
||||
|
||||
for (int x = 0; x < width-2; x++) {
|
||||
printf("#");
|
||||
}
|
||||
printf(".#\n");
|
||||
}
|
||||
|
||||
static u32 day24_gcd(u32 a, u32 b) {
|
||||
u32 R;
|
||||
while ((a % b) != 0) {
|
||||
R = a % b;
|
||||
a = b;
|
||||
b = R;
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
static u32 day24_lcm(u32 a, u32 b) {
|
||||
return a * b / day24_gcd(a, b);
|
||||
}
|
||||
|
||||
static void day24_generate_maps(u16 **maps, u32 count, day24_blizzard *blizzards, u32 blizzard_count, u32 width, u32 height)
|
||||
{
|
||||
memset(maps[0], 0, width * height * sizeof(u16));
|
||||
for (int i = 0; i < blizzard_count; i++) {
|
||||
vec2 *pos = &blizzards[i].pos;
|
||||
u32 idx = pos->y * width + pos->x;
|
||||
maps[0][idx]++;
|
||||
}
|
||||
|
||||
day24_blizzard moving_blizzards[blizzard_count];
|
||||
memcpy(moving_blizzards, blizzards, sizeof(day24_blizzard) * blizzard_count);
|
||||
|
||||
for (int i = 1; i < count; i++) {
|
||||
day24_step(maps[i-1], maps[i], width, height, moving_blizzards, blizzard_count);
|
||||
}
|
||||
}
|
||||
|
||||
static void day24_queue_push(day24_queue *queue, i8 x, i8 y, u16 time)
|
||||
{
|
||||
assert(queue->rear < DAY24_QUEUE_CAPACITY);
|
||||
|
||||
if (queue->front == -1) {
|
||||
queue->front = 0;
|
||||
}
|
||||
|
||||
queue->rear++;
|
||||
queue->x[queue->rear] = x;
|
||||
queue->y[queue->rear] = y;
|
||||
queue->time[queue->rear] = time;
|
||||
}
|
||||
|
||||
|
||||
static void day24_queue_init(day24_queue *queue)
|
||||
{
|
||||
queue->rear = -1;
|
||||
queue->front = -1;
|
||||
}
|
||||
|
||||
static bool day24_queue_is_empty(day24_queue *queue)
|
||||
{
|
||||
return queue->rear == -1;
|
||||
}
|
||||
|
||||
static void day24_queue_pop(day24_queue *queue, i8 *x, i8 *y, u16 *time)
|
||||
{
|
||||
assert(!day24_queue_is_empty(queue));
|
||||
|
||||
*x = queue->x[queue->front];
|
||||
*y = queue->y[queue->front];
|
||||
*time = queue->time[queue->front];
|
||||
queue->front++;
|
||||
if (queue->front > queue->rear) {
|
||||
queue->front = -1;
|
||||
queue->rear = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static bool day24_between(i8 value, i8 min, i8 max)
|
||||
{
|
||||
return min <= value && value <= max;
|
||||
}
|
||||
|
||||
static u16 day24_bfs(u16 **maps, u32 map_count, u32 width, u32 height, vec2 *start, vec2 *goal, u32 start_time)
|
||||
{
|
||||
u32 seen_size = 67108864; // 67108864 = 2^26
|
||||
bool *seen = calloc(seen_size, sizeof(bool));
|
||||
|
||||
day24_queue queue;
|
||||
day24_queue_init(&queue);
|
||||
day24_queue_push(&queue, start->x, start->y, start_time);
|
||||
|
||||
while (!day24_queue_is_empty(&queue)) {
|
||||
i8 x, y;
|
||||
u16 time;
|
||||
day24_queue_pop(&queue, &x, &y, &time);
|
||||
|
||||
time++;
|
||||
|
||||
u32 map_idx = time % map_count;
|
||||
u16 *map = maps[map_idx];
|
||||
|
||||
vec2 offsets[] = { VEC2(1, 0), VEC2(-1, 0), VEC2(0, 1), VEC2(0, -1), VEC2(0, 0) };
|
||||
for (int i = 0; i < ARRAY_LEN(offsets); i++) {
|
||||
i8 new_x = x + offsets[i].x;
|
||||
i8 new_y = y + offsets[i].y;
|
||||
|
||||
if (vec2_eq(goal, new_x, new_y)) {
|
||||
return time;
|
||||
}
|
||||
|
||||
bool is_in_bounds = day24_between(new_x, 1, width-2) && day24_between(new_y, 1, height-2);
|
||||
if (!is_in_bounds && !vec2_eq(start, new_x, new_y)) continue;
|
||||
|
||||
u32 tile_idx = new_y * width + new_x;
|
||||
if (map[tile_idx] > 0) continue;
|
||||
|
||||
u32 seen_key = (map_idx << 16) | (new_x << 8) | (new_y);
|
||||
assert(seen_key < seen_size);
|
||||
if (seen[seen_key]) continue;
|
||||
seen[seen_key] = true;
|
||||
|
||||
day24_queue_push(&queue, new_x, new_y, time);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void day24_part1(void *p)
|
||||
{
|
||||
day24_data *data = (day24_data*)p;
|
||||
|
||||
u32 maps_count = day24_lcm(data->width-2, data->height-2);
|
||||
u16 *maps[maps_count];
|
||||
for (int i = 0; i < maps_count; i++) {
|
||||
maps[i] = malloc(data->width * data->height * sizeof(u16));
|
||||
}
|
||||
day24_generate_maps(maps, maps_count, data->blizzards, data->blizzard_count, data->width, data->height);
|
||||
|
||||
vec2 start = { 1, 0 };
|
||||
vec2 goal = { data->width-2, data->height-1 };
|
||||
printf("%d\n", day24_bfs(maps, maps_count, data->width, data->height, &start, &goal, 0));
|
||||
}
|
||||
|
||||
static void day24_part2(void *p)
|
||||
{
|
||||
day24_data *data = (day24_data*)p;
|
||||
|
||||
u32 maps_count = day24_lcm(data->width-2, data->height-2);
|
||||
u16 *maps[maps_count];
|
||||
for (int i = 0; i < maps_count; i++) {
|
||||
maps[i] = malloc(data->width * data->height * sizeof(u16));
|
||||
}
|
||||
day24_generate_maps(maps, maps_count, data->blizzards, data->blizzard_count, data->width, data->height);
|
||||
|
||||
vec2 start = { 1, 0 };
|
||||
vec2 goal = { data->width-2, data->height-1 };
|
||||
|
||||
u32 time1 = day24_bfs(maps, maps_count, data->width, data->height, &start, &goal , 0);
|
||||
u32 time2 = day24_bfs(maps, maps_count, data->width, data->height, &goal , &start, time1);
|
||||
u32 time3 = day24_bfs(maps, maps_count, data->width, data->height, &start, &goal , time2);
|
||||
printf("%d\n", time3);
|
||||
}
|
||||
|
||||
ADD_SOLUTION(24, day24_parse, day24_part1, day24_part2);
|
2
main.c
2
main.c
@ -31,6 +31,8 @@
|
||||
#include "day20.c"
|
||||
#include "day21.c"
|
||||
#include "day22.c"
|
||||
#include "day23.c"
|
||||
#include "day24.c"
|
||||
|
||||
Solution *find_solution(int day)
|
||||
{
|
||||
|
7
vec2.h
7
vec2.h
@ -1,15 +1,22 @@
|
||||
#ifndef VEC2_H_
|
||||
#define VEC2_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
#include "types.h"
|
||||
|
||||
typedef struct {
|
||||
i32 x, y;
|
||||
} vec2;
|
||||
|
||||
#define VEC2(a, b) { .x = a, .y = b }
|
||||
|
||||
#define TYPEDEF_VEC2(type) typedef struct { type x, y; } vec2_##type
|
||||
|
||||
TYPEDEF_VEC2(u8);
|
||||
TYPEDEF_VEC2(u32);
|
||||
|
||||
static bool vec2_eq(vec2 *A, i32 x, i32 y) {
|
||||
return A->x == x && A->y == y;
|
||||
}
|
||||
|
||||
#endif //VEC2_H_
|
||||
|
Loading…
Reference in New Issue
Block a user