Advertisement
itai-nelken

AOC-2021/day-10-part1

Dec 12th, 2021
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.19 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #define LINE_SIZE 4000
  6. #define STACK_SIZE 5000
  7.  
  8. typedef enum token_type {
  9.     PAREN_OPEN, PAREN_CLOSE,
  10.     BRACKET_OPEN, BRACKET_CLOSE,
  11.     BRACE_OPEN, BRACE_CLOSE,
  12.     AB_OPEN, AB_CLOSE, // AB == angle brackets
  13.     END
  14. } TokenType;
  15.  
  16. const char *t2s(TokenType t) {
  17.     switch(t) {
  18.         case PAREN_OPEN: return "PAREN_OPEN";
  19.         case PAREN_CLOSE: return "PAREN_CLOSE";
  20.         case BRACKET_OPEN: return "BRACKET_OPEN";
  21.         case BRACKET_CLOSE: return "BRACKET_CLOSE";
  22.         case BRACE_OPEN: return "BRACE_OPEN";
  23.         case BRACE_CLOSE: return "BRACE_CLOSE";
  24.         case AB_OPEN: return "AB_OPEN";
  25.         case AB_CLOSE: return "AB_CLOSE";
  26.         case END: return "END";
  27.         default:
  28.             break;
  29.     }
  30.     return "UNKNOWN";
  31. }
  32.  
  33. typedef struct line {
  34.     TokenType types[LINE_SIZE]; // assuming longest line is less than LINE_SIZE characters
  35.     int line;
  36. } Line;
  37.  
  38. void dumpLine(Line *line) {
  39.     printf("line %d\n", line->line);
  40.     for(int i = 0; i < LINE_SIZE && line->types[i] != END; i++) {
  41.         printf("| %s ", t2s(line->types[i]));
  42.     }
  43.     printf("|\n");
  44. }
  45.  
  46. int linelen(Line *l) {
  47.     int size;
  48.     for(size = 0; l->types[size] != END; size++);
  49.     return size;
  50. }
  51.  
  52. void scanLine(char *buffer, Line *line, int linenum) {
  53.     for(int i = 0; i < (int)strlen(buffer); i++) {
  54.         switch(buffer[i]) {
  55.             case '(': line->types[i] = PAREN_OPEN; break;
  56.             case ')': line->types[i] = PAREN_CLOSE; break;
  57.             case '[': line->types[i] = BRACKET_OPEN; break;
  58.             case ']': line->types[i] = BRACKET_CLOSE; break;
  59.             case '{': line->types[i] = BRACE_OPEN; break;
  60.             case '}': line->types[i] = BRACE_CLOSE; break;
  61.             case '<': line->types[i] = AB_OPEN; break;
  62.             case '>': line->types[i] = AB_CLOSE; break;
  63.             case '\n': line->types[i] = END; break;
  64.             default:
  65.                 fprintf(stderr, "ERROR: unknown character '%c' in line %d!\n", buffer[i], linenum);
  66.                 exit(1);
  67.         }
  68.     }
  69.     line->line = linenum;
  70. }
  71.  
  72. Line *readInput(const char *filename, size_t *size) {
  73.     FILE *f = fopen(filename, "r");
  74.     if(f == NULL) return NULL;
  75.  
  76.     fseek(f, 0, SEEK_END);
  77.     size_t fsize = ftell(f);
  78.     rewind(f);
  79.  
  80.     Line *lines = malloc(sizeof(*lines) * fsize);
  81.     int idx = 0;
  82.     char buffer[LINE_SIZE] = {0};
  83.     while(fgets(buffer, LINE_SIZE, f) != NULL) {
  84.         scanLine(buffer, &lines[idx], idx);
  85.         idx++;
  86.         (*size)++;
  87.     }
  88.  
  89.  
  90.     fclose(f);
  91.     return lines;
  92. }
  93.  
  94. TokenType stack[STACK_SIZE] = {-1};
  95. int sp = -1;
  96. void push(TokenType v) {
  97.     if(sp + 1 == STACK_SIZE) {
  98.         fputs("ERROR: stack is full!\n", stderr);
  99.         exit(1);
  100.     }
  101.     stack[++sp] = v;
  102. }
  103. TokenType pop() { return stack[sp--]; }
  104.  
  105. void check(Line *l, int *score) {
  106.     for(int i = 0; i < linelen(l); i++) {
  107.         switch(l->types[i]) {
  108.             case PAREN_OPEN: push(PAREN_OPEN); break;
  109.             case PAREN_CLOSE:
  110.                 if(pop() != PAREN_OPEN) {
  111.                     *score += 3;
  112.                     goto end;
  113.                 }
  114.                 break;
  115.             case BRACKET_OPEN: push(BRACKET_OPEN); break;
  116.             case BRACKET_CLOSE:
  117.                 if(pop() != BRACKET_OPEN) {
  118.                     *score += 57;
  119.                     goto end;
  120.                 }
  121.                 break;
  122.             case BRACE_OPEN: push(BRACE_OPEN); break;
  123.             case BRACE_CLOSE:
  124.                 if(pop() != BRACE_OPEN) {
  125.                     *score += 1197;
  126.                     goto end;
  127.                 }
  128.                 break;
  129.             case AB_OPEN: push(AB_OPEN); break;
  130.             case AB_CLOSE:
  131.                 if(pop() != AB_OPEN) {
  132.                     *score += 25137;
  133.                     goto end;
  134.                 }
  135.                 break;
  136.         }
  137.     }
  138. end:
  139.     return;
  140. }
  141.  
  142. int main(void) {
  143.     size_t size = 0;
  144.     Line *input = readInput("input.txt", &size);
  145.     int score = 0;
  146.  
  147.     for(int i = 0; i < (int)size; i++) {
  148.         check(&input[i], &score);
  149.     }
  150.  
  151.     free(input);
  152.  
  153.     printf("score: %d\n", score);
  154.     return 0;
  155. }
  156.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement