#include #include #include "puzzle_input.h" #include "day.h" #include "queue.h" #include "grid.h" //#define DEBUG #define QUEUE_MAX_SIZE 100 #define GRID_MAX_SIZE 11 typedef struct { uint8_t energy_level; uint8_t popped; } octopus_t; static point_t queue_data_g[QUEUE_MAX_SIZE] = {0}; static octopus_t grid_data_g[GRID_MAX_SIZE*GRID_MAX_SIZE] = {0}; parse_ret_t parse_octo_grid(char * buffer, void * data, uint16_t index) { grid_t * grid = (grid_t *)data; int16_t line_ndx = 0; while (buffer[line_ndx] != '\0') { octopus_t octo; octo.energy_level = buffer[line_ndx] - '0'; octo.popped = 0; grid_set_data(grid, index, line_ndx, &octo); line_ndx++; } grid->width = line_ndx; return PARSER_OK; } static grid_ret_t update_octo_energy_level(grid_t * grid, int ii, int jj) { grid_ret_t ret; octopus_t octo; ret = grid_get_data(grid, ii, jj, &octo); if (ret != GRID_OK) { return ret; } octo.energy_level = octo.energy_level + 1; ret = grid_set_data(grid, ii, jj, &octo); if (ret != GRID_OK) { return ret; } return GRID_OK; } static grid_ret_t set_octo_popped_state(grid_t * grid, int ii, int jj, uint8_t popped) { grid_ret_t ret; octopus_t octo; ret = grid_get_data(grid, ii, jj, &octo); if (ret != GRID_OK) { return ret; } octo.popped = popped; ret = grid_set_data(grid, ii, jj, &octo); if (ret != GRID_OK) { return ret; } return GRID_OK; } int day_11() { parse_ret_t parse_ret = PARSER_OK; grid_ret_t grid_ret = GRID_OK; queue_ret_t queue_ret = QUEUE_OK; queue_t queue = {0}; grid_t grid = {0}; uint16_t grid_height; uint16_t flash_count = 0; grid_init(&grid, GRID_MAX_SIZE, GRID_MAX_SIZE, sizeof(octopus_t), grid_data_g); parse_ret = read_input_single_line("../inputs/day_11.txt", (void *) &grid, GRID_MAX_SIZE, parse_octo_grid, &grid_height); if (parse_ret != PARSER_OK) { printf("Unable to parse input data: %d\n", parse_ret); return -1; } if (grid_height == 0) { printf("No data was parsed from file!\n"); return -2; } grid.height = grid_height; for (int step = 0; step < 1000; step++) { queue_init(&queue, queue_data_g, QUEUE_MAX_SIZE, sizeof(point_t)); for (int ii = 0; ii < grid.height; ii++) { for (int jj = 0; jj < grid.width; jj++) { octopus_t octo; grid_ret = update_octo_energy_level(&grid, ii, jj); if (grid_ret != GRID_OK) { printf("Octo energy level update caused an error: %d\n", grid_ret); return -3; } grid_ret = grid_get_data(&grid, ii, jj, &octo); if (grid_ret != GRID_OK) { printf("Unable to fetch octo: %d\n", grid_ret); return -3; } if (octo.energy_level > 9) { point_t point = {.ii = ii, .jj = jj}; set_octo_popped_state(&grid, ii, jj, 1); if (queue_ret != QUEUE_OK) { printf("Unable push point onto queue: %d\n", queue_ret); return -4; } queue_ret = queue_push(&queue, &point); } } } while (queue.queued_elements > 0) { point_t next_flash; queue_ret = queue_pop(&queue, &next_flash); if (queue_ret != QUEUE_OK) { printf("Unable to pop from queue: %d\n", queue_ret); return -4; } flash_count++; for (int ii_ndx = next_flash.ii-1; ii_ndx <= next_flash.ii+1; ii_ndx++) { for (int jj_ndx = next_flash.jj-1; jj_ndx <= next_flash.jj+1; jj_ndx++) { octopus_t octo; grid_ret = update_octo_energy_level(&grid, ii_ndx, jj_ndx); if (grid_ret == GRID_INDEX_OUT_OF_RANGE) { continue; } if (grid_ret != GRID_OK) { printf("Unable to update octo: %d\n", grid_ret); return -3; } grid_ret = grid_get_data(&grid, ii_ndx, jj_ndx, &octo); if (grid_ret != GRID_OK) { printf("Unable to fetch octo: %d\n", grid_ret); return -3; } if (octo.energy_level > 9 && !octo.popped) { point_t queue_flash = { .ii = ii_ndx, .jj = jj_ndx}; set_octo_popped_state(&grid, ii_ndx, jj_ndx, 1); queue_ret = queue_push(&queue, &queue_flash); if (queue_ret != QUEUE_OK) { printf("Unable push point onto queue: %d\n", queue_ret); return -4; } } } } } #ifdef DEBUG printf("Step %d:\n", step+1); #endif uint8_t step_popped_count = 0; for (int ii = 0; ii < grid.height; ii++) { for (int jj = 0; jj < grid.width; jj++) { octopus_t octo = {0}; grid_get_data(&grid, ii, jj, &octo); if (octo.popped) { step_popped_count++; octo.energy_level = 0; octo.popped = 0; grid_set_data(&grid, ii, jj, &octo); } #ifdef DEBUG printf("%d", octo.energy_level); #endif } #ifdef DEBUG printf("\n"); #endif } #ifdef DEBUG printf("\n\n"); #endif if (step == 99) { printf("PART 1: After 100 steps there were %d flashes!\n", flash_count); } if (step_popped_count == 100) { printf("All octos flashed at the same time step %d", step+1); break; } } return 0; }