aoc

advent of code
git clone git://source.orangerot.dev:/aoc.git
Log | Files | Refs

main3.c (5032B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <stdint.h>
      5 
      6 typedef struct Monkey_ Monkey;
      7 
      8 typedef struct Monkey_ {
      9     __uint128_t item[64];
     10     __uint128_t items, is_multiply, opertant_is_old, operant, test, test_true, test_false, inspections;
     11 } Monkey;
     12 
     13 Monkey* newMonkey() 
     14 {
     15     char *line = NULL;
     16     size_t size;
     17     size_t len;
     18     Monkey *monkey = malloc(sizeof(Monkey));
     19     monkey->inspections = 0;
     20     // items
     21     len = getline(&line, &size, stdin);
     22 
     23     char *begin = line+18;
     24     char *token = NULL;
     25     for (int j = 0; (token = strsep(&begin, ",")); j++) 
     26     {
     27         // printf("%u: %s\n", j, token);
     28         monkey->item[j] = atoi(token);
     29         monkey->items = j+1;
     30     }
     31 
     32     // operation
     33     len = getline(&line, &size, stdin);
     34     monkey->is_multiply = line[23] == '*';
     35     monkey->opertant_is_old = line[25] == 'o';
     36     if (!monkey->opertant_is_old)
     37     {
     38         monkey->operant = atoi(line+25);
     39     }
     40 
     41     // test
     42     len = getline(&line, &size, stdin);
     43     monkey->test = atoi(line+21);
     44 
     45     // test true
     46     len = getline(&line, &size, stdin);
     47     monkey->test_true = atoi(line+29);
     48 
     49     // test true
     50     len = getline(&line, &size, stdin);
     51     monkey->test_false = atoi(line+30);
     52 
     53     len = getline(&line, &size, stdin);
     54     return monkey;
     55 }
     56 
     57 // int priminice(int n)
     58 // {
     59 //     int isPrime;
     60 //     int num = 1;
     61 //     for (int i = 2; i <= n; i++)
     62 //     {
     63 //         if(n % i == 0)
     64 //         {
     65 //             isPrime = 1;
     66 //             for (int j = 2; j <= i/2; j++)
     67 //             {
     68 //                 if(i % j == 0)
     69 //                 {
     70 //                     isPrime = 0;
     71 //                     break;
     72 //                 }
     73 //             } 
     74 //             if(isPrime == 1)
     75 //             {
     76 //                 // printf("\n %d is a Prime Factor ", i);
     77 //                 if ( num % i != 0 )
     78 //                 {
     79 //                     num *= i;
     80 //                 }
     81 //             }	          	
     82 //         }
     83 //     }
     84 //     return num;
     85 // }
     86 
     87 __uint128_t priminice(__uint128_t n)
     88 {
     89     __uint128_t num = 1;
     90     while (n%2 == 0){
     91         // cout<<"2\t";
     92         if ( num % 2 != 0)
     93             num *= 2;
     94         n = n/2;
     95     }
     96     for (int i = 3; i*i <= n; i = i+2){
     97         while (n%i == 0){
     98             // cout<<i<<"\t";
     99             if (num % i != 0)
    100                 num *= i;
    101             n = n/i;
    102         }
    103     }
    104     if (n > 2)
    105     {
    106         if (num % n != 0)
    107             num *= n;
    108         // cout<<n<<"\t";
    109     }
    110     return num;
    111 }
    112 
    113 void inspect(Monkey *monkey, Monkey *monkeys[])
    114 {
    115     monkey->inspections += monkey->items;
    116     for (int i = 0; i < monkey->items; i++)
    117     {
    118         // set operant
    119         __uint128_t operant = monkey->operant;
    120         if (monkey->opertant_is_old)
    121             operant = monkey->item[i];
    122 
    123             // set operation
    124         if (monkey->is_multiply )
    125         {
    126             monkey->item[i] *= operant;
    127         } else {
    128             monkey->item[i] += operant;
    129         }
    130 
    131         // monkey->item[i] /= 3;
    132 
    133         // throw item based on test
    134         int throw = monkey->test_true;
    135         if (monkey->item[i] % monkey->test != 0)
    136         {
    137             throw = monkey->test_false;
    138         }
    139 
    140         monkeys[throw]->item[monkeys[throw]->items] = priminice(monkey->item[i]);
    141         monkeys[throw]->items++;
    142     }
    143     monkey->items = 0;
    144 }
    145 
    146 int main(int argc, char *argv[])
    147 {
    148 
    149     int monkeys = 0;
    150     Monkey *monkey[10] = { };
    151 
    152     char *line = NULL;
    153     size_t size;
    154     size_t len;
    155     __uint128_t active1 = 0, active2 = 0;
    156 
    157     while ((len = getline(&line, &size, stdin)) != -1)
    158     {
    159         // create monkeys
    160         Monkey *new = newMonkey();
    161         monkey[monkeys] = new;
    162         monkeys++;
    163         
    164         // print monkey attributes
    165         printf("Items:");
    166         for (int i = 0; i < new->items; i++)
    167         {
    168             printf("%lud ", new->item[i]);
    169         }
    170         printf("\n %d %d %d %d %d %d\n\n",
    171             new->is_multiply,
    172             new->opertant_is_old,
    173             new->operant,
    174             new->test,
    175             new->test_true,
    176             new->test_false
    177                 );
    178     }
    179 
    180     for (int i = 0; i < atoi(argv[1]); i++)
    181     {
    182         // do inspection
    183         for (int ii = 0; ii < monkeys; ii++)
    184         {
    185             inspect(monkey[ii], monkey);
    186         }
    187         
    188         // output rounds
    189         printf("Round %d\n", i);
    190         for (int ii = 0; ii < monkeys; ii++)
    191         {
    192             printf("Monkey %d: ", ii);
    193             for (int iii = 0; iii < monkey[ii]->items; iii++)
    194             {
    195                 printf("%lu ", monkey[ii]->item[iii]);
    196             }
    197             printf("\n");
    198         }
    199     }
    200     
    201     // get two most active monkeys
    202     for (int i = 0; i < monkeys; i++)
    203     {
    204         if (monkey[i]->inspections > active1) 
    205         {
    206             active2 = active1;
    207             active1 = monkey[i]->inspections;
    208         }
    209         printf("Monkey %d inspected items %d times. \n", i, monkey[i]->inspections);
    210     }
    211 
    212     printf("Monkey biz: \n%lu %lu %lu\n", active1, active2, active1 * active2);
    213 }
    214