Advertisement
musifter

AoC 2022, day 20 (C, part 2)

Dec 20th, 2022
1,130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 2.69 KB | Source Code | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdint.h>
  4. #include <assert.h>
  5.  
  6. #define  MAX_NUM        10000
  7. #define  DECRYPT_KEY    811589153
  8.  
  9. typedef struct node_def {
  10.     int64_t             value;
  11.     struct node_def *   next;
  12.     struct node_def *   prev;
  13. } node_def;
  14.  
  15. // Insert item into ring after dest, return ptr to it
  16. node_def * insert_node( node_def *item, node_def *dest ) {
  17.     item->next = dest->next;
  18.     item->prev = dest;
  19.     dest->next->prev = item;
  20.     dest->next = item;
  21.     return (item);
  22. }
  23.  
  24. // Remove item from ring, return ptr to it
  25. node_def * remove_node( node_def *item ) {
  26.     item->next->prev = item->prev;
  27.     item->prev->next = item->next;
  28.     return (item);
  29. }
  30.  
  31. // Used for creating ring... allocates nodes adds them after prev
  32. node_def * create_node( node_def *prev, int64_t val ) {
  33.     node_def *new = malloc( sizeof( node_def ) );
  34.     assert( new != NULL );
  35.  
  36.     new->value = val;
  37.     if (prev != NULL) {
  38.         insert_node( new, prev );
  39.     } else {
  40.         new->next = new;
  41.         new->prev = new;
  42.     }
  43.  
  44.     return (new);
  45. }
  46.  
  47. // Print out the ring, up to max_len items
  48. void print_ring( node_def *start, int max_len ) {
  49.     node_def *curr = start;
  50.  
  51.     int i = 0;
  52.     do {
  53.         printf( "%ld, ", curr->value );
  54.         curr = curr->next;
  55.     } while (curr != start && ++i < max_len);
  56.  
  57.     if (curr != start) {
  58.         printf( "..." );
  59.     }
  60.     printf( "\n" );
  61. }
  62.  
  63. int main() {
  64.     node_def *  order[ MAX_NUM ];
  65.     node_def *  ring = NULL;
  66.     node_def *  zero = NULL;
  67.     int         len  = 0;
  68.     int64_t     num;
  69.  
  70.     // Read in ring (get pointer to zero node)
  71.     while (scanf( "%ld", &num ) == 1) {
  72.         num *= DECRYPT_KEY;
  73.         order[len++] = ring = create_node( ring, num );
  74.         if (num == 0) {
  75.             zero = ring;
  76.         }
  77.     }
  78.  
  79.     // Mix the list
  80.     for (int t = 0; t < 10; t++) {
  81.         for (int i = 0; i < len; i++) {
  82.             node_def *curr = order[i];
  83.  
  84.             const int dist = curr->value % (len - 1);
  85.             if (dist) {
  86.                 node_def *dest = (dist > 0) ? remove_node( curr )
  87.                                             : remove_node( curr )->prev;
  88.  
  89.                 for (int j = 0; j < abs(dist); j++) {
  90.                     dest = (dist > 0) ? dest->next : dest->prev;
  91.                 }
  92.  
  93.                 insert_node( curr, dest );
  94.             }
  95.         }
  96.     }
  97.  
  98.     // Get result
  99.     node_def *curr = zero;
  100.     int64_t   sum  = 0;
  101.     for (int i = 0; i <= 3000; i++, curr = curr->next) {
  102.         if (i % 1000 == 0) {
  103.             sum += curr->value;
  104.             printf( "%4d: %ld\n", i, curr->value );
  105.         }
  106.     }
  107.  
  108.     printf( "Part 2: %ld\n", sum );
  109. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement