#include #include #include #include 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; } }