Day 11 Check In

* These data structures are coming in handy
main
Joey Hines 2021-12-12 10:07:39 -07:00
parent 303194dfbc
commit 185fc4a8b1
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
8 changed files with 331 additions and 6 deletions

View File

@ -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)

10
inputs/day_11.txt 100644
View File

@ -0,0 +1,10 @@
3322874652
5636588857
7755117548
5854121833
2856682477
3124873812
1541372254
8634383236
2424323348
2265635842

View File

@ -11,5 +11,6 @@ int day_7();
int day_8();
int day_9();
int day_10();
int day_11();
#endif //AOC_2021_DAY_H

218
src/day_11.c 100644
View File

@ -0,0 +1,218 @@
#include <stdio.h>
#include <stdint.h>
#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;
}

View File

@ -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];

62
src/grid.c 100644
View File

@ -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;
}

35
src/grid.h 100644
View File

@ -0,0 +1,35 @@
//
// Created by joey on 12/12/21.
//
#ifndef AOC_2021_GRID_H
#define AOC_2021_GRID_H
#include <stddef.h>
#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

View File

@ -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;