Advertisement
musifter

AoC 2022, day 3 (C)

Dec 3rd, 2022
642
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.84 KB | Source Code | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <stdint.h>
  5.  
  6. // priority is 1 to 52, for a-zA-Z
  7. int priority( char letter ) {
  8.     return (islower(letter) ? letter - 'a' + 1
  9.                             : letter - 'A' + 27);
  10. }
  11.  
  12. // use bits to do a set on letters, trailing zeros is priority
  13. uint64_t as_bit_set( const char str[], int length ) {
  14.     uint64_t set = 0;
  15.  
  16.     for (int i = 0; i < length; i++) {
  17.         set |= (uint64_t) 1 << priority( str[i] );
  18.     }
  19.  
  20.     return (set);
  21. }
  22.  
  23. // Get trailing zeros after only remaining bit in set is the priority.
  24. // Simple, but just as fast as __builtin_ctzl or a binary search on my machine.
  25. int bit_priority( uint64_t bit ) {
  26.     int pri = 0;
  27.  
  28.     while (bit >>= 1) {
  29.         pri++;
  30.     }
  31.  
  32.     return (pri);
  33. }
  34.  
  35. int main() {
  36.     char        line[80];
  37.  
  38.     int         part1 = 0;
  39.     int         part2 = 0;
  40.  
  41.     // state machine variables for part 2
  42.     int         state = 0;
  43.     uint64_t    badge;
  44.  
  45.     while (fgets( line, sizeof(line), stdin ) != NULL) {
  46.         // part 1 - intersection of compartments
  47.         const int half = strlen( line ) / 2;
  48.  
  49.         const uint64_t comp1 = as_bit_set( line, half );
  50.         const uint64_t comp2 = as_bit_set( &line[half], half );
  51.  
  52.         uint64_t inter = comp1 & comp2;
  53.         part1 += bit_priority( inter );
  54.  
  55.         // part 2 - union to get full sack, intersect groups of three
  56.         uint64_t all = comp1 | comp2;
  57.  
  58.         // state machine
  59.         state = (state + 1) % 3;
  60.         if (state == 1) {
  61.             badge = all;            // new badge
  62.         } else {
  63.             badge &= all;           // intersect with sack
  64.             if (state == 0) {
  65.                 part2 += bit_priority( badge );
  66.             }
  67.         }
  68.     }
  69.  
  70.     printf( "Part 1: %d\n", part1 );
  71.     printf( "Part 2: %d\n", part2 );
  72. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement