From d853ba0b10eb9078556ef5e0d7e049005cfde82b Mon Sep 17 00:00:00 2001 From: Joey Hines Date: Thu, 2 Dec 2021 19:16:08 -0700 Subject: [PATCH] Day 2 Complete * Added puzzle_input.c to help handle common input parsing * Accepts a parser callback function to do the day specific parsing * Updated day_1 to use new parsing system --- CMakeLists.txt | 2 +- inputs/day_2.txt | 1000 ++++++++++++++++++++++++++++++++++++++++++++ src/day.h | 1 + src/day_1.c | 90 +--- src/day_2.c | 120 ++++++ src/main.c | 3 + src/puzzle_input.c | 87 ++++ src/puzzle_input.h | 23 + 8 files changed, 1247 insertions(+), 79 deletions(-) create mode 100644 inputs/day_2.txt create mode 100644 src/day_2.c create mode 100644 src/puzzle_input.c create mode 100644 src/puzzle_input.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5ac7296..5b086a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,4 +3,4 @@ project(aoc_2021 C) set(CMAKE_C_STANDARD 99) -add_executable(aoc_2021 src/main.c src/day_1.c src/day.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) diff --git a/inputs/day_2.txt b/inputs/day_2.txt new file mode 100644 index 0000000..cde6bfc --- /dev/null +++ b/inputs/day_2.txt @@ -0,0 +1,1000 @@ +forward 5 +down 9 +forward 2 +up 2 +forward 4 +forward 4 +up 5 +down 3 +forward 2 +forward 9 +down 7 +forward 2 +down 2 +forward 1 +up 9 +forward 1 +forward 4 +up 5 +down 9 +forward 8 +forward 3 +up 1 +down 2 +down 3 +forward 7 +forward 2 +up 3 +forward 9 +forward 9 +down 3 +up 8 +forward 5 +forward 7 +forward 2 +down 7 +forward 5 +down 4 +up 7 +forward 8 +forward 1 +down 3 +down 1 +forward 6 +up 7 +forward 6 +down 3 +forward 9 +forward 6 +up 3 +down 1 +forward 8 +up 7 +down 9 +down 2 +down 1 +down 5 +forward 4 +down 8 +forward 2 +down 5 +down 6 +down 5 +forward 5 +down 8 +up 8 +forward 3 +forward 4 +forward 8 +forward 9 +down 2 +forward 7 +forward 3 +forward 9 +down 3 +up 1 +down 5 +forward 2 +down 9 +down 2 +down 5 +down 2 +down 9 +up 3 +forward 6 +up 9 +down 1 +forward 8 +up 6 +down 1 +forward 1 +up 1 +forward 3 +down 8 +down 1 +down 9 +forward 4 +forward 1 +down 3 +forward 8 +down 9 +forward 7 +up 6 +down 8 +down 6 +down 8 +down 7 +down 1 +down 8 +down 1 +forward 5 +down 9 +forward 4 +down 2 +forward 8 +up 1 +forward 7 +down 7 +down 6 +forward 4 +forward 6 +down 2 +down 2 +up 7 +down 2 +up 9 +forward 6 +forward 3 +down 8 +forward 9 +down 9 +down 9 +down 8 +forward 2 +forward 5 +forward 8 +forward 1 +down 3 +forward 1 +forward 2 +forward 9 +up 5 +forward 4 +forward 2 +down 6 +forward 3 +forward 7 +forward 1 +forward 8 +down 7 +forward 4 +up 3 +down 9 +up 2 +forward 2 +forward 7 +down 9 +up 9 +forward 9 +up 8 +up 7 +down 8 +down 9 +forward 1 +forward 5 +up 7 +down 3 +up 9 +forward 9 +down 4 +down 7 +down 7 +down 1 +down 4 +down 5 +up 2 +forward 2 +forward 2 +forward 6 +down 7 +forward 7 +down 5 +forward 8 +down 7 +forward 6 +down 2 +up 2 +down 5 +down 1 +up 4 +down 8 +up 9 +forward 1 +down 9 +down 6 +down 8 +up 7 +up 1 +forward 7 +down 8 +forward 1 +down 4 +down 2 +forward 3 +forward 6 +forward 8 +down 2 +forward 7 +forward 8 +up 3 +down 1 +down 8 +up 3 +down 4 +down 5 +forward 6 +forward 9 +down 3 +up 2 +down 9 +up 2 +down 3 +down 9 +forward 4 +forward 6 +down 7 +down 8 +down 4 +forward 7 +up 2 +down 5 +up 3 +down 5 +up 1 +up 1 +forward 5 +forward 9 +down 9 +up 4 +up 4 +up 8 +up 5 +forward 7 +forward 6 +up 6 +down 5 +forward 4 +forward 3 +up 6 +down 6 +forward 5 +up 6 +up 7 +forward 1 +forward 2 +forward 5 +down 3 +forward 6 +down 6 +down 3 +up 9 +down 4 +down 5 +down 4 +forward 1 +down 1 +forward 3 +up 4 +forward 1 +forward 5 +up 3 +forward 6 +forward 5 +forward 9 +forward 6 +down 2 +forward 2 +down 1 +down 4 +forward 6 +forward 8 +down 8 +up 5 +forward 8 +forward 3 +forward 1 +forward 3 +forward 6 +down 1 +down 9 +up 7 +down 2 +forward 6 +down 4 +down 7 +down 5 +forward 2 +down 1 +forward 2 +forward 8 +forward 4 +up 3 +down 1 +forward 6 +forward 3 +down 3 +down 9 +forward 1 +up 5 +forward 3 +forward 3 +up 5 +down 7 +forward 8 +up 5 +forward 2 +forward 2 +down 6 +up 8 +up 5 +forward 2 +forward 1 +down 9 +forward 7 +down 5 +forward 3 +down 3 +down 5 +down 5 +up 7 +down 8 +forward 2 +forward 4 +forward 5 +forward 1 +down 6 +forward 3 +down 1 +down 7 +forward 3 +forward 7 +down 5 +down 3 +forward 6 +down 3 +down 2 +down 4 +down 9 +forward 7 +down 2 +up 2 +up 6 +up 9 +up 8 +forward 9 +down 1 +forward 4 +forward 2 +forward 7 +forward 2 +down 8 +down 3 +forward 4 +forward 6 +down 8 +forward 7 +forward 6 +up 3 +down 6 +down 1 +down 3 +down 8 +down 2 +down 7 +down 9 +forward 4 +forward 7 +forward 8 +forward 5 +forward 9 +up 5 +down 2 +forward 9 +forward 6 +up 6 +forward 7 +down 2 +down 3 +forward 4 +down 6 +down 1 +down 2 +down 8 +forward 3 +down 3 +forward 3 +down 5 +up 8 +down 5 +forward 8 +down 1 +forward 1 +forward 4 +forward 7 +down 2 +down 5 +forward 5 +down 8 +forward 2 +down 2 +forward 5 +forward 6 +forward 4 +down 7 +up 7 +down 1 +forward 7 +forward 8 +down 6 +up 7 +forward 6 +up 6 +down 8 +forward 5 +forward 8 +up 4 +up 2 +up 1 +down 8 +down 6 +up 2 +down 5 +down 1 +forward 5 +forward 7 +down 2 +up 3 +up 3 +forward 9 +down 1 +forward 6 +down 2 +forward 2 +down 1 +down 9 +forward 7 +down 5 +down 8 +up 1 +forward 1 +down 7 +forward 3 +down 4 +up 4 +down 6 +forward 1 +forward 3 +down 2 +forward 3 +forward 5 +forward 6 +up 2 +up 9 +forward 4 +down 4 +up 1 +up 3 +forward 8 +forward 1 +down 9 +down 9 +forward 2 +down 1 +up 9 +up 3 +up 1 +up 5 +forward 6 +down 9 +forward 6 +forward 9 +forward 6 +forward 4 +up 2 +down 6 +up 3 +forward 3 +forward 1 +up 4 +forward 7 +down 9 +down 3 +forward 9 +down 4 +down 8 +down 3 +up 8 +down 8 +down 8 +forward 2 +forward 8 +up 9 +forward 2 +up 6 +forward 7 +down 1 +forward 5 +forward 4 +forward 1 +forward 7 +up 9 +down 8 +forward 1 +up 5 +forward 9 +forward 2 +forward 8 +down 1 +forward 7 +down 2 +up 8 +down 6 +up 9 +up 3 +down 6 +forward 5 +down 1 +forward 1 +forward 6 +forward 6 +up 1 +forward 5 +forward 1 +up 2 +forward 9 +forward 6 +down 3 +up 1 +forward 7 +forward 2 +down 1 +forward 6 +down 3 +up 2 +down 3 +down 8 +forward 4 +down 2 +up 7 +down 6 +up 5 +down 7 +forward 4 +down 9 +down 3 +forward 2 +up 5 +up 4 +forward 9 +down 1 +up 2 +forward 4 +down 9 +down 8 +forward 5 +forward 2 +down 5 +forward 6 +down 4 +forward 7 +forward 1 +forward 6 +down 3 +down 9 +forward 9 +forward 2 +forward 6 +down 7 +down 5 +down 3 +forward 7 +down 3 +down 3 +down 4 +down 4 +down 7 +down 7 +down 7 +up 7 +up 9 +up 7 +up 3 +up 4 +down 9 +down 4 +up 3 +forward 2 +up 1 +down 9 +down 6 +up 1 +up 2 +down 7 +down 9 +up 2 +forward 7 +down 4 +forward 3 +down 1 +down 7 +forward 7 +up 7 +forward 3 +forward 1 +forward 6 +forward 2 +down 9 +forward 8 +up 8 +down 8 +down 9 +up 1 +down 4 +down 6 +down 8 +up 4 +down 1 +forward 1 +forward 1 +forward 4 +forward 7 +forward 1 +down 4 +forward 5 +up 3 +forward 4 +down 5 +down 1 +up 2 +down 7 +forward 7 +down 7 +up 9 +down 9 +down 3 +up 2 +up 8 +up 8 +up 7 +forward 7 +forward 5 +forward 3 +forward 2 +down 5 +forward 4 +forward 1 +down 6 +down 1 +forward 8 +down 6 +down 3 +down 5 +down 9 +down 3 +forward 7 +forward 6 +down 6 +forward 9 +up 7 +forward 3 +up 5 +down 5 +down 5 +forward 4 +up 6 +down 6 +forward 3 +up 2 +forward 4 +up 1 +down 5 +forward 6 +forward 9 +down 2 +up 2 +down 2 +up 7 +forward 3 +up 2 +forward 9 +forward 5 +down 5 +down 7 +down 8 +down 6 +up 9 +up 5 +forward 7 +down 8 +down 1 +forward 7 +up 2 +forward 4 +forward 2 +up 9 +down 8 +forward 1 +forward 7 +down 2 +down 3 +down 6 +down 3 +forward 1 +up 6 +forward 8 +down 9 +down 9 +forward 8 +up 8 +down 6 +forward 4 +up 1 +forward 5 +down 3 +down 7 +down 7 +down 3 +up 2 +forward 4 +down 9 +forward 2 +down 9 +forward 9 +forward 4 +forward 5 +down 4 +forward 1 +up 1 +forward 4 +up 3 +up 4 +forward 7 +down 9 +forward 6 +down 1 +down 1 +down 2 +down 4 +forward 7 +forward 8 +forward 6 +down 8 +forward 2 +down 3 +up 5 +forward 2 +up 5 +forward 8 +down 8 +down 8 +up 8 +forward 6 +up 1 +down 3 +forward 6 +down 1 +forward 9 +up 1 +forward 7 +forward 7 +down 1 +forward 5 +forward 2 +up 7 +down 1 +forward 2 +down 4 +forward 3 +down 9 +forward 6 +up 5 +forward 1 +forward 5 +down 7 +forward 6 +down 8 +forward 9 +down 1 +forward 9 +down 1 +forward 5 +up 9 +forward 1 +forward 6 +forward 5 +down 7 +down 6 +down 5 +down 9 +forward 9 +down 2 +down 8 +down 8 +forward 2 +forward 3 +forward 3 +down 3 +forward 8 +forward 8 +down 8 +forward 1 +up 1 +forward 4 +down 7 +forward 1 +up 2 +forward 9 +forward 1 +down 6 +up 9 +down 3 +down 1 +up 1 +up 6 +up 7 +forward 9 +up 2 +forward 4 +up 8 +down 6 +forward 3 +forward 7 +down 6 +down 5 +down 3 +forward 5 +down 1 +forward 2 +forward 9 +down 8 +up 6 +forward 3 +forward 2 +up 7 +down 3 +forward 5 +forward 9 +down 5 +down 1 +up 4 +down 8 +forward 1 +forward 3 +forward 3 +down 2 +forward 5 +down 1 +forward 2 +up 3 +forward 8 +down 2 +up 8 +down 6 +down 8 +forward 4 +down 4 +up 7 +up 6 +down 7 +forward 2 +up 3 +forward 3 +down 8 +forward 8 +down 5 +forward 5 +down 3 +up 7 +down 1 +down 2 +up 8 +down 6 +up 6 +down 7 +forward 5 +up 3 +forward 7 +forward 2 +down 9 +down 1 +down 4 +down 7 +forward 9 +up 7 +forward 5 +up 8 +forward 8 +up 1 +forward 2 +down 7 +down 5 +down 6 +down 4 +up 4 +forward 5 +forward 6 +up 4 +forward 8 +forward 4 +forward 3 +up 5 +down 6 +up 4 +forward 8 +down 7 +forward 3 +down 2 +down 7 +down 5 +down 4 +forward 5 +up 4 +forward 4 +down 7 +down 3 +down 9 +down 7 +forward 2 +forward 1 +down 7 +down 8 +forward 1 +forward 2 +down 5 +up 1 +down 1 +forward 5 +down 2 +forward 9 +forward 7 +down 2 +forward 6 +forward 9 +up 5 +forward 3 +up 5 +forward 7 +down 6 +down 3 +up 3 +down 4 +forward 2 +up 4 +forward 5 +up 9 +down 3 +up 1 +down 1 +up 3 +forward 4 +forward 5 +down 3 +forward 5 +down 6 +down 2 +forward 5 +forward 3 +down 7 +down 8 +forward 4 +down 5 +forward 7 +forward 2 +forward 7 +down 7 +up 1 +forward 6 +down 1 +forward 1 +down 4 +forward 1 +up 6 +forward 8 +forward 6 +forward 7 +up 6 +up 7 +up 2 +down 9 +forward 4 +up 3 +down 1 +down 1 +forward 3 +down 4 +down 6 +down 8 +forward 9 +forward 6 +down 1 +forward 5 \ No newline at end of file diff --git a/src/day.h b/src/day.h index 046602f..a517e78 100644 --- a/src/day.h +++ b/src/day.h @@ -2,5 +2,6 @@ #define AOC_2021_DAY_H int day_1(); +int day_2(); #endif //AOC_2021_DAY_H diff --git a/src/day_1.c b/src/day_1.c index f16b27a..a617cd7 100644 --- a/src/day_1.c +++ b/src/day_1.c @@ -4,77 +4,11 @@ #include #include "day.h" +#include "puzzle_input.h" #define DATA_MAX_LEN 2048 -int parse_long_from_buff(char * buffer, int64_t * val) { - *val = strtol(buffer, NULL, 16); - - if (*val == LONG_MIN || *val == LONG_MAX) { - return -2; - } - - return 0; -} - -int read_input(const char * file_path, int64_t *data, uint16_t max_len) { - char buffer[64]; - int c; - int ret = 0; - FILE * file = fopen(file_path, "r"); - int data_ndx = 0; - - if (file != NULL) { - int buffer_ndx = 0; - while ((c = fgetc(file)) != EOF) { - if (c == '\n') { - buffer[buffer_ndx] = 0; - - ret = parse_long_from_buff(buffer, &data[data_ndx]); - - if (ret < 0) { - break; - } - - data_ndx++; - - if (data_ndx >= max_len) { - ret = -3; - break; - } - - buffer_ndx = 0; - } - else { - buffer[buffer_ndx] = (char)c; - buffer_ndx++; - } - } - - if (buffer_ndx > 0) { - ret = parse_long_from_buff(buffer, &data[data_ndx]); - - if (ret == 0) { - data_ndx++; - } - } - } - else { - ret = -1; - } - - if (ret == 0) { - ret = data_ndx; - } - - if (file != NULL) { - fclose(file); - } - - return ret; -} - -void part_1(const int64_t * data, uint16_t data_len) { +static void part_1(const int64_t * data, uint16_t data_len) { int64_t last_value; int16_t inc_count = 0; @@ -89,7 +23,7 @@ void part_1(const int64_t * data, uint16_t data_len) { printf("PART 1: %d values increased!\n", inc_count); } -void part_2(const int64_t * data, uint16_t data_len) { +static void part_2(const int64_t * data, uint16_t data_len) { int64_t old_window_sum; int64_t window_sum; int16_t inc_count = 0; @@ -111,19 +45,19 @@ void part_2(const int64_t * data, uint16_t data_len) { int day_1() { char * path = "../inputs/day_1.txt"; - int data_len; + uint16_t data_len; int64_t data[DATA_MAX_LEN]; - data_len = read_input(path, data, DATA_MAX_LEN); + parse_ret_t res = read_input(path, (void *)data, DATA_MAX_LEN, parse_long_from_buff, &data_len); - if (data_len < 0) { - printf("read_input returned an error: %d\n", data_len); - return data_len; + if (res == PARSER_OK) { + part_1(data, data_len); + part_2(data, data_len); + } + else { + printf("Failed to parse data: %d\n", res); + return res; } - - part_1(data, data_len); - - part_2(data, data_len); return 0; } \ No newline at end of file diff --git a/src/day_2.c b/src/day_2.c new file mode 100644 index 0000000..44071f1 --- /dev/null +++ b/src/day_2.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include +#include + +#include "puzzle_input.h" +#include "day.h" + +#define MAX_COURSE_SIZE 1024 + +typedef enum { + FORWARD, + DOWN , + UP, +} course_dir_t; + +typedef struct { + course_dir_t dir; + int64_t units; +} course_entry_t; + +int parse_course_entry(char * buffer, void * data, uint16_t data_index) { + char * save_ptr; + char * dir_str = strtok_r(buffer, " ", &save_ptr); + char * unit_str = strtok_r(NULL, " ", &save_ptr); + parse_ret_t ret; + int64_t units; + + ret = parse_long(unit_str, &units); + + if (ret == PARSER_OK) { + course_dir_t dir; + + switch (dir_str[0]) { + case 'f': + dir = FORWARD; + break; + case 'd': + dir = DOWN; + break; + case 'u': + dir = UP; + break; + default: + ret = PARSER_INVALID; + } + + if (ret == PARSER_OK) { + course_entry_t entry = { + .dir = dir, + .units = units + }; + + course_entry_t *course = (course_entry_t *)data; + course[data_index] = entry; + } + } + + return ret; +} + +static void part_1(course_entry_t * course, uint16_t course_len) { + int64_t horizontal_pos = 0; + int64_t depth = 0; + + for (int course_ndx = 0; course_ndx < course_len; course_ndx++) { + int dir_sign = 1; + switch (course[course_ndx].dir) { + case FORWARD: + horizontal_pos += course[course_ndx].units; + break; + case UP: + dir_sign = -1; + case DOWN: + depth += dir_sign*course[course_ndx].units; + } + } + + printf("PART 1: Final Horizontal * Final Depth = %ld\n", horizontal_pos*depth); +} + +static void part_2(course_entry_t * course, uint16_t course_len) { + int64_t horizontal_pos = 0; + int64_t depth = 0; + int64_t aim = 0; + + for (int course_ndx = 0; course_ndx < course_len; course_ndx++) { + int dir_sign = 1; + int64_t units = course[course_ndx].units; + switch (course[course_ndx].dir) { + case FORWARD: + horizontal_pos += units; + depth += units * aim; + break; + case UP: + dir_sign = -1; + case DOWN: + aim += dir_sign*units; + } + } + + printf("PART 2: Final Horizontal * Final Depth = %ld\n", horizontal_pos*depth); +} + +int day_2() { + course_entry_t course[MAX_COURSE_SIZE]; + uint16_t data_len; + parse_ret_t res = read_input("../inputs/day_2.txt", (void *)course, MAX_COURSE_SIZE, parse_course_entry, &data_len); + + if (res == PARSER_OK) { + part_1(course, data_len); + part_2(course, data_len); + } + else { + printf("Failed to parse data: %d", res); + } +} + + diff --git a/src/main.c b/src/main.c index 156f094..035189d 100644 --- a/src/main.c +++ b/src/main.c @@ -19,6 +19,9 @@ int main(int argc, char * argv[]) { case 1: day_1(); break; + case 2: + day_2(); + break; default: printf("Invalid day ding dong!\n"); return -2; diff --git a/src/puzzle_input.c b/src/puzzle_input.c new file mode 100644 index 0000000..b8cf1f6 --- /dev/null +++ b/src/puzzle_input.c @@ -0,0 +1,87 @@ +#include +#include +#include +#include +#include "puzzle_input.h" + +parse_ret_t parse_long(char * buffer, int64_t *val) { + *val = strtol(buffer, NULL, 10); + + if (*val == LONG_MIN || *val == LONG_MAX) { + return PARSER_INVALID; + } + + return PARSER_OK; + +} + +parse_ret_t parse_long_from_buff(char * buffer, void * data, uint16_t index) { + uint64_t * int_data = (uint64_t *)data; + uint64_t val; + int ret; + + ret = parse_long(buffer, (int64_t *)&val); + + if (ret != PARSER_OK) { + return ret; + } + + int_data[index] = val; + + return PARSER_OK; +} + +parse_ret_t read_input(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len) { + char buffer[64]; + int c; + int ret = 0; + FILE * file = fopen(file_path, "r"); + uint16_t data_ndx = 0; + + if (file != NULL) { + int buffer_ndx = 0; + while ((c = fgetc(file)) != EOF) { + if (c == '\n') { + buffer[buffer_ndx] = 0; + + ret = parser(buffer, data, data_ndx); + + if (ret != PARSER_OK) { + break; + } + + data_ndx++; + + if (data_ndx >= max_len) { + ret = PARSER_RANGE_OVERFLOW; + break; + } + + buffer_ndx = 0; + } + else { + buffer[buffer_ndx] = (char)c; + buffer_ndx++; + } + } + + if (buffer_ndx > 0) { + ret = parser(buffer, data, data_ndx); + + if (ret == PARSER_OK) { + data_ndx++; + } + } + } + else { + ret = PARSE_FILE_ERR; + } + + if (file != NULL) { + fclose(file); + } + + *len = data_ndx; + + return ret; +} \ No newline at end of file diff --git a/src/puzzle_input.h b/src/puzzle_input.h new file mode 100644 index 0000000..1b9e372 --- /dev/null +++ b/src/puzzle_input.h @@ -0,0 +1,23 @@ +#ifndef AOC_2021_PUZZLE_INPUT_H +#define AOC_2021_PUZZLE_INPUT_H + +#include + +typedef enum { + PARSER_OK = 0, + PARSER_INVALID = -1, + PARSER_RANGE_OVERFLOW = -2, + PARSE_FILE_ERR = -3, +} parse_ret_t; + +typedef parse_ret_t (*input_parser_t)(char * buffer, void * data, uint16_t index); + +parse_ret_t read_input(const char * file_path, void * data, uint16_t max_len, input_parser_t parser, uint16_t * len); + +// Parsers +parse_ret_t parse_long_from_buff(char * buffer, void * data, uint16_t index); + +//Helpers +parse_ret_t parse_long(char * buffer, int64_t * val); + +#endif //AOC_2021_PUZZLE_INPUT_H