advent2022

Advent of Code 2022 Solutions
git clone https://todayiwilllaunchmyinfantsonintoorbit.com/advent2022.git
Log | Files | Refs

3b.c (2413B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <errno.h>
      5 
      6 int compare_char(const char *first, const char *second) {
      7   return *first - *second;
      8 }
      9 
     10 int main(void) {
     11   FILE *input = fopen("input", "r");
     12   char *line_1 = NULL, *line_2 = NULL, *line_3 = NULL;
     13   size_t buf_len;
     14   unsigned int prio_sum = 0;
     15   
     16   while (!feof(input)) {
     17     if (getline(&line_1, &buf_len, input) != -1
     18         && getline(&line_2, &buf_len, input) != -1
     19         && getline(&line_3, &buf_len, input) != -1) {
     20 
     21       // Get line lengths
     22       size_t len_1 = strlen(line_1);
     23       if (len_1 > 2 && line_1[len_1 - 1] == '\n') {
     24         // Truncate
     25         line_1[len_1 - 1] = 0;
     26         len_1 -= 1;
     27       }
     28       size_t len_2 = strlen(line_2);
     29       if (len_2 > 2 && line_2[len_2 - 1] == '\n') {
     30         // Truncate
     31         line_2[len_2 - 1] = 0;
     32         len_2 -= 1;
     33       }
     34       size_t len_3 = strlen(line_3);
     35       if (len_3 > 2 && line_3[len_3 - 1] == '\n') {
     36         // Truncate
     37         line_3[len_3 - 1] = 0;
     38         len_3 -= 1;
     39       }
     40 
     41       // Sort all three sacks
     42       qsort(line_1, len_1, sizeof(char), compare_char);
     43       qsort(line_2, len_2, sizeof(char), compare_char);
     44       qsort(line_3, len_3, sizeof(char), compare_char);
     45 
     46       // Spin over the three compartments and find any duplicates
     47       for (int i = 0, j = 0, k = 0;i < len_1 && j < len_2 && k < len_3;i++) {
     48         // Run to the end of the current run
     49         while (i < (len_1 - 1) && line_1[i] == line_1[i + 1])
     50           i++;
     51 
     52         // Skip any characters less than first_half[i]
     53         while (j < len_2 && line_2[j] < line_1[i])
     54           j++;
     55         while (k < len_3 && line_3[k] < line_1[i])
     56           k++;
     57 
     58         //printf("Comparing %c, %c, %c\n", line_1[i], line_2[j], line_3[k]);
     59 
     60         if (j < len_2 && k < len_3 && line_1[i] == line_2[j] && line_1[i] == line_3[k]) {
     61           char dup = line_1[i];
     62           if (dup >= 'a' && dup <= 'z') {
     63             prio_sum += dup - 96;
     64           } else {
     65             prio_sum += dup - 38;
     66           }
     67         }
     68       }
     69 
     70       free(line_1);
     71       free(line_2);
     72       free(line_3);
     73       line_1 = line_2 = line_3 = NULL;
     74     } else {
     75       free(line_1);
     76       if (line_2)
     77         free(line_2);
     78       if (line_3)
     79         free(line_3);
     80       if (errno) {
     81         strerror(NULL);
     82         exit(EXIT_FAILURE);
     83       }
     84     }
     85   }
     86   printf("Priority sum: %i\n", prio_sum);
     87 
     88   fclose(input);
     89 }