diff --git a/CMakeLists.txt b/CMakeLists.txt index fbb04a5..9e4619c 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) +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) target_link_libraries(aoc_2021 m) diff --git a/inputs/day_6.txt b/inputs/day_6.txt new file mode 100644 index 0000000..57e0ce5 --- /dev/null +++ b/inputs/day_6.txt @@ -0,0 +1 @@ +4,1,3,2,4,3,1,4,4,1,1,1,5,2,4,4,2,1,2,3,4,1,2,4,3,4,5,1,1,3,1,2,1,4,1,1,3,4,1,2,5,1,4,2,2,1,1,1,3,1,5,3,1,2,1,1,1,1,4,1,1,1,2,2,1,3,1,3,1,3,4,5,1,2,2,1,1,1,4,1,5,1,3,1,3,4,1,3,2,3,4,4,4,3,4,5,1,3,1,3,5,1,1,1,1,1,2,4,1,2,1,1,1,5,1,1,2,1,3,1,4,2,3,4,4,3,1,1,3,5,3,1,1,5,2,4,1,1,3,5,1,4,3,1,1,4,2,1,1,1,1,1,1,3,1,1,1,1,1,4,5,1,2,5,3,1,1,3,1,1,1,1,5,1,2,5,1,1,1,1,1,1,3,5,1,3,2,1,1,1,1,1,1,1,4,5,1,1,3,1,5,1,1,1,1,3,3,1,1,1,4,4,1,1,4,1,2,1,4,4,1,1,3,4,3,5,4,1,1,4,1,3,1,1,5,5,1,2,1,2,1,2,3,1,1,3,1,1,2,1,1,3,4,3,1,1,3,3,5,1,2,1,4,1,1,2,1,3,1,1,1,1,1,1,1,4,5,5,1,1,1,4,1,1,1,2,1,2,1,3,1,3,1,1,1,1,1,1,1,5 \ No newline at end of file diff --git a/src/day.h b/src/day.h index 7be662a..f14f014 100644 --- a/src/day.h +++ b/src/day.h @@ -6,5 +6,6 @@ int day_2(); int day_3(); int day_4(); int day_5(); +int day_6(); #endif //AOC_2021_DAY_H diff --git a/src/day_6.c b/src/day_6.c new file mode 100644 index 0000000..18e746c --- /dev/null +++ b/src/day_6.c @@ -0,0 +1,83 @@ +#include +#include + +#include "puzzle_input.h" +#include "day.h" + +#define STATES_MAX_LEN 500 +#define FISH_DAYS 9 + +uint8_t states_g[STATES_MAX_LEN]; + + +typedef struct { + uint64_t spawn_count[FISH_DAYS]; + uint8_t day_ndx; +} fish_buffer_t; + +void insert_fish_at_ndx(fish_buffer_t * buff, uint8_t day_ndx, uint64_t count) { + uint8_t norm_ndx = (buff->day_ndx + day_ndx) % FISH_DAYS; + buff->spawn_count[norm_ndx] += count; +} + +uint64_t fish_today(fish_buffer_t * buff) { + return buff->spawn_count[buff->day_ndx]; +} + +void inc_day(fish_buffer_t * buff) { + buff->day_ndx = (buff->day_ndx + 1) % FISH_DAYS; +} + +parse_ret_t parse_byte_from_buffer(char * buffer, void * data, uint16_t index) { + uint8_t * initial_states = (uint8_t *)data; + int64_t val; + parse_ret_t res; + + res = parse_long(buffer, &val, 10); + + if (res != PARSER_OK) { + return res; + } + + initial_states[index] = (uint8_t)val; + + return PARSER_OK; +} + +int day_6() { + parse_ret_t res; + uint16_t len; + uint16_t day = 0; + uint64_t fish_count; + fish_buffer_t fish_buffer = {0}; + + res = read_input_split_on("../inputs/day_6.txt", (void *)states_g, 500, parse_byte_from_buffer, &len, ','); + + if (res != PARSER_OK) { + printf("Unable to parse input data: %d", res); + return -1; + } + + for (int initial_ndx = 0; initial_ndx < len; initial_ndx++) { + fish_buffer.spawn_count[states_g[initial_ndx]]++; + } + + fish_count = len; + + while (day < 256) { + uint64_t spawns_today = fish_today(&fish_buffer); + inc_day(&fish_buffer); + insert_fish_at_ndx(&fish_buffer, 6, spawns_today); + + fish_count += spawns_today; + + day++; + + if (day == 80) { + printf("PART 1: Fish count: %lu\n", fish_count); + } + } + + printf("PART 2: Fish count: %lu\n", fish_count); + return 0; +} diff --git a/src/main.c b/src/main.c index ab43528..7f54e60 100644 --- a/src/main.c +++ b/src/main.c @@ -31,6 +31,9 @@ int main(int argc, char * argv[]) { case 5: day_5(); break; + case 6: + day_6(); + break; default: printf("Invalid day ding dong!\n"); return -2; diff --git a/src/puzzle_input.c b/src/puzzle_input.c index 2c16cf7..4cf43e7 100644 --- a/src/puzzle_input.c +++ b/src/puzzle_input.c @@ -46,7 +46,7 @@ parse_ret_t parse_long_base_2_from_buff(char * buffer, void * data, uint16_t ind return parse_long_base_from_buff(buffer, data, index, 2); } -parse_ret_t read_input_single_line(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len) { +parse_ret_t read_input_split_on(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len, char sep) { char buffer[BUFFER_SIZE]; int c; int ret = 0; @@ -56,7 +56,7 @@ parse_ret_t read_input_single_line(const char * file_path, void * data, uint16_t if (file != NULL) { int buffer_ndx = 0; while ((c = fgetc(file)) != EOF) { - if (c == '\n') { + if (c == sep) { buffer[buffer_ndx] = 0; ret = parser(buffer, data, data_ndx); @@ -177,3 +177,7 @@ parse_ret_t read_input_multi_line(const char * file_path, void * data, uint16_t return ret; } + +parse_ret_t read_input_single_line(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len) { + read_input_split_on(file_path, data, max_len, parser, len, '\n'); +} diff --git a/src/puzzle_input.h b/src/puzzle_input.h index 52466f5..60a18bd 100644 --- a/src/puzzle_input.h +++ b/src/puzzle_input.h @@ -14,6 +14,7 @@ typedef enum { typedef parse_ret_t (*input_parser_t)(char * buffer, void * data, uint16_t index); parse_ret_t read_input_single_line(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len); +parse_ret_t read_input_split_on(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len, char split); parse_ret_t read_input_multi_line(const char * file_path, void * data, uint16_t max_len, char * sep, input_parser_t parser, uint16_t * len); // Parsers