89 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			89 lines
		
	
	
		
			2.4 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <stdbool.h>
 | |
| 
 | |
| #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;
 | |
| }
 |