My solutions to the advent of code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
3.0 KiB

3 years ago
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
int countLines(FILE *fp){
long int lines =0;
while (EOF != (fscanf(fp, "%*[^\n]"), fscanf(fp,"%*c")))
++lines;
return lines;
}
int cmp_asc_unsigned_long(const void *a, const void *b) {
return *(unsigned long*)a > *(unsigned long*)b;
}
unsigned int getScore(char symbol){
switch (symbol) {
case ')':
return 1;
break;
case ']':
return 2;
break;
case '}':
return 3;
break;
case '>':
return 4;
break;
default:
return 0;
break;
}
}
void corruptLine(char expected, char found, FILE *fp){
fscanf(fp, "%*s");
}
int lineLength(FILE *fp){
unsigned int lineLength=0;
char ch = fgetc(fp);
while ( ch != '\n' && ch != EOF ){
lineLength++;
ch = fgetc(fp);
if ( lineLength > 30 ) break;
}
return lineLength;
}
char reverse(char ch){
switch (ch) {
case '[':
return ']';
break;
case ']':
return '[';
break;
case '(':
return ')';
break;
case ')':
return '(';
break;
case '{':
return '}';
break;
case '}':
return '{';
break;
case '<':
return '>';
break;
case '>':
return '<';
break;
}
return 0;
}
int main( int argc, char *argv[] ){
if( argc == 2 ) {
FILE *fp=fopen(argv[1], "r");
char ch = '\0';
int lineCount = countLines(fp);
rewind(fp);
unsigned long completionScores[lineCount];
memset(completionScores, '0', sizeof(unsigned long) * lineCount);
int compCount = 0;
while ( !feof(fp) ){
unsigned int lineStart = ftell(fp);
ch = getc(fp);
if ( EOF == ch ) break;
fseek(fp, lineStart, SEEK_SET);
unsigned int length = lineLength(fp);
fseek(fp, lineStart, SEEK_SET);
char line[length+1];
memset(line, '\0', sizeof(char) * (length + 1));
char depthArr[(length+1)/2];
memset(line, 'a', sizeof(char) * (length + 1));
unsigned int depth=0;
memset(line, '\0', sizeof(char) * ( ( length + 1 ) / 2 ));
bool corrupt=false;
while (1){
ch = getc(fp);
// Cant break out of switch and loop at the same time
if ( ch == '\n' ) break;
switch (ch) {
case '[':
case '(':
case '{':
case '<':
depthArr[depth] = ch;
depth++;
break;
case ']':
case ')':
case '}':
case '>':
depth--;
if ( depthArr[depth] != reverse(ch) ){
corruptLine( reverse(depthArr[ depth ]), ch, fp );
corrupt = true;
}
break;
}
}
if ( !corrupt ){
unsigned long score=0;
for ( int i = depth-1; i >= 0; i-- ){
score *= 5;
score += getScore(reverse(depthArr[i]));
}
completionScores[compCount++] = score;
}
}
qsort(completionScores, compCount, sizeof(unsigned long), cmp_asc_unsigned_long);
for ( int i = 0; i < compCount; i++ ){
printf("Score %i: %lu\n", i, completionScores[i]);
}
printf("Middle score: %lu\n", completionScores[( compCount / 2 )]);
fclose(fp);
return 0;
} else {
printf("You need to provide a file\n");
return 1;
}
}