From 185fc4a8b1c006ee618777884f3ba564391b2d36 Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Sun, 12 Dec 2021 10:07:39 -0700 Subject: [PATCH] Day 11 Check In * These data structures are coming in handy --- CMakeLists.txt | 2 +- inputs/day_11.txt | 10 +++ src/day.h | 1 + src/day_11.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++ src/day_9.c | 6 +- src/grid.c | 62 +++++++++++++ src/grid.h | 35 ++++++++ src/main.c | 3 + 8 files changed, 331 insertions(+), 6 deletions(-) create mode 100644 inputs/day_11.txt create mode 100644 src/day_11.c create mode 100644 src/grid.c create mode 100644 src/grid.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 762f556..3dd9fb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,5 +3,5 @@ project(aoc_2021 C) set(CMAKE_C_STANDARD 99) -add_executable(aoc_2021 src/main.c src/day_1.c src/day.h src/day_2.c src/puzzle_input.c src/puzzle_input.h src/day_3.c src/day_4.c src/day_5.c src/day_6.c src/day_7.c src/day_8.c src/day_9.c src/queue.c src/queue.h src/day_10.c src/stack.c src/stack.h) +add_executable(aoc_2021 src/main.c src/day_1.c src/day.h src/day_2.c src/puzzle_input.c src/puzzle_input.h src/day_3.c src/day_4.c src/day_5.c src/day_6.c src/day_7.c src/day_8.c src/day_9.c src/queue.c src/queue.h src/day_10.c src/stack.c src/stack.h src/day_11.c src/grid.c src/grid.h) target_link_libraries(aoc_2021 m) diff --git a/inputs/day_11.txt b/inputs/day_11.txt new file mode 100644 index 0000000..652096a --- /dev/null +++ b/inputs/day_11.txt @@ -0,0 +1,10 @@ +3322874652 +5636588857 +7755117548 +5854121833 +2856682477 +3124873812 +1541372254 +8634383236 +2424323348 +2265635842 \ No newline at end of file diff --git a/src/day.h b/src/day.h index 8a5b712..c981edb 100644 --- a/src/day.h +++ b/src/day.h @@ -11,5 +11,6 @@ int day_7(); int day_8(); int day_9(); int day_10(); +int day_11(); #endif //AOC_2021_DAY_H diff --git a/src/day_11.c b/src/day_11.c new file mode 100644 index 0000000..2523627 --- /dev/null +++ b/src/day_11.c @@ -0,0 +1,218 @@ +#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; +} \ No newline at end of file diff --git a/src/day_9.c b/src/day_9.c index 2ff0998..57a73a5 100644 --- a/src/day_9.c +++ b/src/day_9.c @@ -5,15 +5,11 @@ #include "puzzle_input.h" #include "day.h" #include "queue.h" +#include "grid.h" #define MAX_WIDTH 100 #define QUEUE_SIZE 500 -typedef struct { - int ii; - int jj; -} point_t; - typedef struct { int8_t map_data[MAX_WIDTH*MAX_WIDTH]; uint8_t basin[MAX_WIDTH*MAX_WIDTH]; diff --git a/src/grid.c b/src/grid.c new file mode 100644 index 0000000..71747db --- /dev/null +++ b/src/grid.c @@ -0,0 +1,62 @@ + +#include "grid.h" +#include "puzzle_input.h" +#include "string.h" + +static grid_ret_t index_in_range(const grid_t * grid, int ii, int jj) { + return (ii >= grid->height) || (ii < 0) || (jj >= grid->width) || (jj < 0); +} + +static void * get_index_ptr(const grid_t * grid, int ii, int jj) { + return grid->data + (jj * grid->elem_size) + (ii * grid->width * grid->elem_size); +} + + + +grid_ret_t grid_init(grid_t * grid, size_t max_height, size_t max_width, size_t elem_size, void * data_store) { + grid->max_height = max_height; + grid->max_width = max_width; + grid->elem_size = elem_size; + grid->data = data_store; + grid->height = max_height; + grid->width = max_width; + + return GRID_OK; +} + +grid_ret_t grid_get_data(const grid_t * grid, int ii, int jj, void * ret) { + if (index_in_range(grid, ii, jj)) { + return GRID_INDEX_OUT_OF_RANGE; + } + else { + void * index = get_index_ptr(grid, ii, jj); + + if (ret != NULL) { + memcpy(ret, index, grid->elem_size); + } + else { + return GRID_INVALID_RET_PTR; + } + } + + return GRID_OK; +} + +grid_ret_t grid_set_data(const grid_t * grid, int ii, int jj, void * val) { + if (index_in_range(grid, ii, jj)) { + return GRID_INDEX_OUT_OF_RANGE; + } + else { + void * index = get_index_ptr(grid, ii, jj); + + if (val != NULL) { + memcpy(index, val, grid->elem_size); + } + else { + return GRID_INVALID_RET_PTR; + } + } + + return GRID_OK; + +} \ No newline at end of file diff --git a/src/grid.h b/src/grid.h new file mode 100644 index 0000000..bd80d89 --- /dev/null +++ b/src/grid.h @@ -0,0 +1,35 @@ +// +// Created by joey on 12/12/21. +// + +#ifndef AOC_2021_GRID_H +#define AOC_2021_GRID_H + +#include +#include "puzzle_input.h" + +typedef enum { + GRID_OK = 0, + GRID_INDEX_OUT_OF_RANGE = -1, + GRID_INVALID_RET_PTR = -2, +} grid_ret_t; + +typedef struct { + int ii; + int jj; +} point_t; + +typedef struct { + void * data; + size_t width; + size_t height; + size_t max_width; + size_t max_height; + size_t elem_size; +} grid_t; + +grid_ret_t grid_init(grid_t * grid, size_t max_height, size_t max_width, size_t elem_size, void * data_store); +grid_ret_t grid_get_data(const grid_t * grid, int ii, int jj, void * ret); +grid_ret_t grid_set_data(const grid_t * grid, int ii, int jj, void * val); + +#endif //AOC_2021_GRID_H diff --git a/src/main.c b/src/main.c index 55b9bdf..101a352 100644 --- a/src/main.c +++ b/src/main.c @@ -46,6 +46,9 @@ int main(int argc, char * argv[]) { case 10: day_10(); break; + case 11: + day_11(); + break; default: printf("Invalid day ding dong!\n"); return -2;