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
main
Joey Hines 2021-12-02 19:16:08 -07:00
parent a02302a516
commit d853ba0b10
No known key found for this signature in database
GPG Key ID: 80F567B5C968F91B
8 changed files with 1247 additions and 79 deletions

View File

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

1000
inputs/day_2.txt 100644

File diff suppressed because it is too large Load Diff

View File

@ -2,5 +2,6 @@
#define AOC_2021_DAY_H
int day_1();
int day_2();
#endif //AOC_2021_DAY_H

View File

@ -4,77 +4,11 @@
#include <limits.h>
#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;
}

120
src/day_2.c 100644
View File

@ -0,0 +1,120 @@
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#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);
}
}

View File

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

87
src/puzzle_input.c 100644
View File

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

23
src/puzzle_input.h 100644
View File

@ -0,0 +1,23 @@
#ifndef AOC_2021_PUZZLE_INPUT_H
#define AOC_2021_PUZZLE_INPUT_H
#include <stdint.h>
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