Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define LINE_SIZE 4000
- #define STACK_SIZE 5000
- typedef enum token_type {
- PAREN_OPEN, PAREN_CLOSE,
- BRACKET_OPEN, BRACKET_CLOSE,
- BRACE_OPEN, BRACE_CLOSE,
- AB_OPEN, AB_CLOSE, // AB == angle brackets
- END
- } TokenType;
- const char *t2s(TokenType t) {
- switch(t) {
- case PAREN_OPEN: return "PAREN_OPEN";
- case PAREN_CLOSE: return "PAREN_CLOSE";
- case BRACKET_OPEN: return "BRACKET_OPEN";
- case BRACKET_CLOSE: return "BRACKET_CLOSE";
- case BRACE_OPEN: return "BRACE_OPEN";
- case BRACE_CLOSE: return "BRACE_CLOSE";
- case AB_OPEN: return "AB_OPEN";
- case AB_CLOSE: return "AB_CLOSE";
- case END: return "END";
- default:
- break;
- }
- return "UNKNOWN";
- }
- typedef struct line {
- TokenType types[LINE_SIZE]; // assuming longest line is less than LINE_SIZE characters
- int line;
- } Line;
- void dumpLine(Line *line) {
- printf("line %d\n", line->line);
- for(int i = 0; i < LINE_SIZE && line->types[i] != END; i++) {
- printf("| %s ", t2s(line->types[i]));
- }
- printf("|\n");
- }
- int linelen(Line *l) {
- int size;
- for(size = 0; l->types[size] != END; size++);
- return size;
- }
- void scanLine(char *buffer, Line *line, int linenum) {
- for(int i = 0; i < (int)strlen(buffer); i++) {
- switch(buffer[i]) {
- case '(': line->types[i] = PAREN_OPEN; break;
- case ')': line->types[i] = PAREN_CLOSE; break;
- case '[': line->types[i] = BRACKET_OPEN; break;
- case ']': line->types[i] = BRACKET_CLOSE; break;
- case '{': line->types[i] = BRACE_OPEN; break;
- case '}': line->types[i] = BRACE_CLOSE; break;
- case '<': line->types[i] = AB_OPEN; break;
- case '>': line->types[i] = AB_CLOSE; break;
- case '\n': line->types[i] = END; break;
- default:
- fprintf(stderr, "ERROR: unknown character '%c' in line %d!\n", buffer[i], linenum);
- exit(1);
- }
- }
- line->line = linenum;
- }
- Line *readInput(const char *filename, size_t *size) {
- FILE *f = fopen(filename, "r");
- if(f == NULL) return NULL;
- fseek(f, 0, SEEK_END);
- size_t fsize = ftell(f);
- rewind(f);
- Line *lines = malloc(sizeof(*lines) * fsize);
- int idx = 0;
- char buffer[LINE_SIZE] = {0};
- while(fgets(buffer, LINE_SIZE, f) != NULL) {
- scanLine(buffer, &lines[idx], idx);
- idx++;
- (*size)++;
- }
- fclose(f);
- return lines;
- }
- TokenType stack[STACK_SIZE] = {-1};
- int sp = -1;
- void push(TokenType v) {
- if(sp + 1 == STACK_SIZE) {
- fputs("ERROR: stack is full!\n", stderr);
- exit(1);
- }
- stack[++sp] = v;
- }
- TokenType pop() { return stack[sp--]; }
- void check(Line *l, int *score) {
- for(int i = 0; i < linelen(l); i++) {
- switch(l->types[i]) {
- case PAREN_OPEN: push(PAREN_OPEN); break;
- case PAREN_CLOSE:
- if(pop() != PAREN_OPEN) {
- *score += 3;
- goto end;
- }
- break;
- case BRACKET_OPEN: push(BRACKET_OPEN); break;
- case BRACKET_CLOSE:
- if(pop() != BRACKET_OPEN) {
- *score += 57;
- goto end;
- }
- break;
- case BRACE_OPEN: push(BRACE_OPEN); break;
- case BRACE_CLOSE:
- if(pop() != BRACE_OPEN) {
- *score += 1197;
- goto end;
- }
- break;
- case AB_OPEN: push(AB_OPEN); break;
- case AB_CLOSE:
- if(pop() != AB_OPEN) {
- *score += 25137;
- goto end;
- }
- break;
- }
- }
- end:
- return;
- }
- int main(void) {
- size_t size = 0;
- Line *input = readInput("input.txt", &size);
- int score = 0;
- for(int i = 0; i < (int)size; i++) {
- check(&input[i], &score);
- }
- free(input);
- printf("score: %d\n", score);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement