advent-of-code-2024/day-10/main.c

84 lines
2.2 KiB
C

#include "aoc.h"
typedef struct CellBitMap {
u64 *bits;
int size;
} CellBitMap;
static void
bitmap_set_bit(CellBitMap *bitmap, int index) {
bitmap->bits[index / 64] |= 1ULL << (index % 64);
}
static int
bitmap_popcount(CellBitMap *bitmap) {
int count = 0;
for (int i = 0; i < bitmap->size; i++) {
count += __builtin_popcountll(bitmap->bits[i]);
}
return count;
}
static void
bitmap_clear(CellBitMap *bitmap) {
memset(bitmap->bits, 0, bitmap->size * sizeof(u64));
}
static const int OFFSETS[][2] = {
{ 0, -1},
{ 1, 0},
{ 0, 1},
{-1, 0},
};
static int
find_trails_and_compute_rating(Grid *grid, int x, int y, char current_number, CellBitMap *bitmap) {
ASSERT(grid->grid[y * grid->width + x] == current_number);
int result = 0;
if (current_number == '9') {
int index = y * grid->width + x;
bitmap_set_bit(bitmap, index);
result = 1;
}
else {
for (int i = 0; i < 4; i++) {
int dx = OFFSETS[i][0];
int dy = OFFSETS[i][1];
int nx = x + dx;
int ny = y + dy;
if (nx >= 0 && nx < grid->width && ny >= 0 && ny < grid->height) {
char neighbor = grid->grid[ny * grid->width + nx];
if (neighbor == current_number + 1) {
result += find_trails_and_compute_rating(grid, nx, ny, neighbor, bitmap);
}
}
}
}
return result;
}
int main(int argc, char **argv) {
Arena *arena = make_arena(Megabytes(1));
str input = read_file(arena, argv[1]);
Grid grid = parse_grid(str_trim(input), arena);
CellBitMap bitmap = {0};
bitmap.size = (grid.width * grid.height + 63) / 64;
bitmap.bits = ARENA_ALLOC_ARRAY(arena, u64, bitmap.size);
i32 part_1 = 0;
i32 part_2 = 0;
for (int y = 0; y < grid.height; y++) {
for (int x = 0; x < grid.width; x++) {
if (grid.grid[y * grid.width + x] == '0') {
part_2 += find_trails_and_compute_rating(&grid, x, y, '0', &bitmap);
int score = bitmap_popcount(&bitmap);
bitmap_clear(&bitmap);
part_1 += score;
}
}
}
printf("%d\n", part_1);
printf("%d\n", part_2);
}