aoc-2021/src/day_10.c

193 lines
5.6 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include "puzzle_input.h"
#include "day.h"
#include "stack.h"
#define MAX_LINES 200
#define MAX_LINE_LEN 200
#define NAV_DATA_SIZE (MAX_LINES * MAX_LINE_LEN)
#define MAX_STACK_SIZE 100
static char nav_data_g[MAX_LINES*MAX_LINE_LEN];
static char stack_data_g[MAX_STACK_SIZE];
typedef enum {
NONE,
PARENTHESES,
SQUARE_BRACKET,
CURLY_BRACKET,
ANGLE_BRACKET,
} char_classes_t;
parse_ret_t parse_str_line(char * buffer, void * data, uint16_t index) {
char * nav_data = ((char *)data) + (index*MAX_LINE_LEN);
strncpy(nav_data, buffer, MAX_LINE_LEN);
return PARSER_OK;
}
static int uint64_t_cmp(const void * a, const void * b) {
uint64_t a_int = *(uint64_t *)a;
uint64_t b_int = *(uint64_t *)b;
if (a_int < b_int) {
return -1;
}
else if (a_int > b_int) {
return 1;
}
else {
return 0;
}
}
int day_10() {
parse_ret_t res;
uint16_t len;
uint32_t syntax_error_score = 0;
int autocomplete_ndx = 0;
uint64_t autocomplete_scores[MAX_LINES];
res = read_input_single_line("../inputs/day_10.txt", (void *)nav_data_g, NAV_DATA_SIZE, parse_str_line, &len);
if (res != PARSER_OK) {
printf("Failed to parse puzzle input: %d\n", res);
return -1;
}
for (uint16_t line_ndx = 0; line_ndx < len; line_ndx++) {
char * star_line_ptr = nav_data_g + (line_ndx * MAX_LINE_LEN);
char * line_ptr = star_line_ptr;
stack_t stack = {};
stack_init(&stack, stack_data_g, MAX_STACK_SIZE, sizeof(char));
uint8_t corrupted = 0;
while (*line_ptr != '\0') {
char_classes_t invalid_char = NONE;
uint8_t char_class = NONE;
stack_ret_t stack_ret;
switch (*line_ptr) {
case '(':
char_class = PARENTHESES;
stack_ret = stack_push(&stack, &char_class);
break;
case '[':
char_class = SQUARE_BRACKET;
stack_ret = stack_push(&stack, &char_class);
break;
case '{':
char_class = CURLY_BRACKET;
stack_ret = stack_push(&stack, &char_class);
break;
case '<':
char_class = ANGLE_BRACKET;
stack_ret = stack_push(&stack, &char_class);
break;
case ')':
stack_ret = stack_pop(&stack, &char_class);
if (char_class != PARENTHESES) {
invalid_char = PARENTHESES;
}
break;
case ']':
stack_ret = stack_pop(&stack, &char_class);
if (char_class != SQUARE_BRACKET) {
invalid_char = SQUARE_BRACKET;
}
break;
case '}':
stack_ret = stack_pop(&stack, &char_class);
if (char_class != CURLY_BRACKET) {
invalid_char = CURLY_BRACKET;
}
break;
case '>':
stack_ret = stack_pop(&stack, &char_class);
if (char_class != ANGLE_BRACKET) {
invalid_char = ANGLE_BRACKET;
}
break;
default:
printf("Invalid char: %c\n", *line_ptr);
return -2;
}
if (stack_ret == STACK_FULL) {
printf("Need more stack space!\n");
return -3;
}
if (invalid_char != NONE) {
corrupted = 1;
switch (invalid_char) {
case PARENTHESES:
syntax_error_score += 3;
break;
case SQUARE_BRACKET:
syntax_error_score += 57;
break;
case CURLY_BRACKET:
syntax_error_score += 1197;
break;
case ANGLE_BRACKET:
syntax_error_score += 25137;
break;
default:
break;
}
break;
}
line_ptr++;
}
if (!corrupted) {
uint64_t autocomplete_score = 0;
char_classes_t next = 0;
while (stack_pop(&stack, &next) == STACK_OK) {
autocomplete_score *= 5;
switch (next) {
case PARENTHESES:
autocomplete_score += 1;
break;
case SQUARE_BRACKET:
autocomplete_score += 2;
break;
case CURLY_BRACKET:
autocomplete_score += 3;
break;
case ANGLE_BRACKET:
autocomplete_score += 4;
break;
default:
break;
}
}
autocomplete_scores[autocomplete_ndx++] = autocomplete_score;
}
}
qsort((void *)autocomplete_scores, autocomplete_ndx, sizeof(uint64_t), uint64_t_cmp);
int middle_ndx = autocomplete_ndx/2;
printf("PART 1: The total syntax error score is %d\n", syntax_error_score);
printf("PART 2: The total autocomplete score is %lu\n", autocomplete_scores[middle_ndx]);
return 0;
}