#include #include #include #include #include "../../lib/aoc.h" typedef struct Map { char *data; int data_length; int width; int height; int current_level; int positions[10000]; int positions_count; } Map; void ascend(Map *map, bool dedupe) { char search_for = map->current_level + 1 + '0'; int positions[10000]; int positions_count = 0; for (int i = 0; i < map->positions_count; i++) { int p = map->positions[i]; if (p - map->width >= 0 && map->data[p - map->width] == search_for) positions[positions_count++] = p - map->width; if (map->data[p - 1] == search_for) positions[positions_count++] = p - 1; if (map->data[p + 1] == search_for) positions[positions_count++] = p + 1; if (p + map->width < map->data_length && map->data[p + map->width] == search_for) positions[positions_count++] = p + map->width; } if (dedupe) { qsort(positions, positions_count, sizeof(int), aoc_sort_int); int deduped_positions[10000]; int deduped_positions_count = 0; for (int i = 0; i < positions_count - 1; i++) { if (positions[i] != positions[i+1]) { deduped_positions[deduped_positions_count++] = positions[i]; } } deduped_positions[deduped_positions_count++] = positions[positions_count - 1]; map->positions_count = deduped_positions_count; memcpy(&(map->positions), &deduped_positions, deduped_positions_count * sizeof(int)); map->current_level++; } else { map->positions_count = positions_count; memcpy(&(map->positions), &positions, positions_count * sizeof(int)); map->current_level++; } } int calculate_score(Map *map, int index, bool dedupe) { if (map->data[index] != '0') return 0; map->current_level = 0; map->positions[0] = index; map->positions_count = 1; for (int i = 0; i < 9; i++) { ascend(map, dedupe); } return map->positions_count; } int main() { char *input = aoc_read_input(); int input_length = strlen(input); Map m; m.data = input; m.data_length = input_length; m.width = strchr(input, '\n') - input + 1; m.height = input_length - m.width; int score = 0; int big_score = 0; for (int i = 0; i < input_length; i++) { score += calculate_score(&m, i, true); big_score += calculate_score(&m, i, false); } printf("Part 1: %d\n", score); printf("Part 2: %d\n", big_score); aoc_free(); return 0; }