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 systemmain
parent
a02302a516
commit
d853ba0b10
|
@ -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)
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -2,5 +2,6 @@
|
|||
#define AOC_2021_DAY_H
|
||||
|
||||
int day_1();
|
||||
int day_2();
|
||||
|
||||
#endif //AOC_2021_DAY_H
|
||||
|
|
88
src/day_1.c
88
src/day_1.c
|
@ -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);
|
||||
|
||||
if (data_len < 0) {
|
||||
printf("read_input returned an error: %d\n", data_len);
|
||||
return data_len;
|
||||
}
|
||||
parse_ret_t res = read_input(path, (void *)data, DATA_MAX_LEN, parse_long_from_buff, &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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue