parent
303194dfbc
commit
185fc4a8b1
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
3322874652
|
||||
5636588857
|
||||
7755117548
|
||||
5854121833
|
||||
2856682477
|
||||
3124873812
|
||||
1541372254
|
||||
8634383236
|
||||
2424323348
|
||||
2265635842
|
|
@ -11,5 +11,6 @@ int day_7();
|
|||
int day_8();
|
||||
int day_9();
|
||||
int day_10();
|
||||
int day_11();
|
||||
|
||||
#endif //AOC_2021_DAY_H
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue