diff --git a/day-10/input.txt b/day-10/input.txt new file mode 100644 index 0000000..d3da5e8 --- /dev/null +++ b/day-10/input.txt @@ -0,0 +1,45 @@ +676781023010121078756541010565410126589652103 +787692014523134569687238921076321087676543012 +896543210674013278798107831089980896567122107 +654100134985329143237356540123678925498033498 +783210325676438050123445443294541012321044589 +694309018984567267034576356789032008769655678 +345678567823432178125689219878102109678724369 +456969430214563089068701008765210234569013212 +327854321005478873879010123674377654354321001 +218901232876569912968123294589988912210132432 +107650343985567803451054387487676903432101561 +210545674783498712589965236596567876543650170 +323432185692105605678876145645430967858743289 +214981092185434104987986001034321458969801001 +105670123076393213098887632125010321578932102 +789889874101284332106798540136521230432840013 +876776965692379876087034567287650145521051224 +965460150789561045696129898398010676670569345 +234321041276432038765408765498723487989678496 +165432132345987129932317454389654395432310987 +074540122187656087801326761230101276211001236 +783458043090345196540410890121210989303456545 +892169834901210105432589789032367893456327896 +701078985810012234501678776543456302587410187 +667654856798943107657578905494543211693217896 +578983012367874038748765412387687600784506787 +457832343455465129889854307898990521099615690 +300761567854321012934781212387121434988794321 +211650434969482103245690101236012345670188760 +672349123478091014132386789845621012873279454 +589678012562182365001675632736790123964560303 +432547001601276478976543541345887654456781212 +321232118762345569885012310212994569323998800 +210321129098710378894322343200123478010878901 +300410030123601256765011056123430765430765432 +321567542034510349810782987001521894321045645 +434788601945654878725693965432676541013236012 +095699717898783965434344876501987034901107823 +187659826500192854303239884567698127872787934 +234549834410201601214138793298012016543396543 +067812765325360519871025682105623456671230123 +154908901876451456789014871234702965580145674 +233217010945962359874323960189811874495432985 +945606321034876543265221054076320432356781876 +876545432321089012100100123165410321065690165 diff --git a/day-10/main.c b/day-10/main.c new file mode 100644 index 0000000..d61773e --- /dev/null +++ b/day-10/main.c @@ -0,0 +1,83 @@ +#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); +} diff --git a/day-10/test.txt b/day-10/test.txt new file mode 100644 index 0000000..a305b9d --- /dev/null +++ b/day-10/test.txt @@ -0,0 +1,4 @@ +0123 +1234 +8765 +9876 diff --git a/day-10/test2.txt b/day-10/test2.txt new file mode 100644 index 0000000..cada9b3 --- /dev/null +++ b/day-10/test2.txt @@ -0,0 +1,8 @@ +89010123 +78121874 +87430965 +96549874 +45678903 +32019012 +01329801 +10456732