193 lines
5.6 KiB
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;
|
|
} |