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.
155 lines
3.0 KiB
155 lines
3.0 KiB
#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; |
|
} |
|
}
|
|
|