127 lines
3.2 KiB
C
127 lines
3.2 KiB
C
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
|
|
typedef struct Monkey {
|
|
unsigned long business;
|
|
unsigned long items[32];
|
|
int count;
|
|
char op;
|
|
int val;
|
|
int test;
|
|
int true;
|
|
int false;
|
|
} Monkey;
|
|
|
|
int compar(const void *a, const void *b) {
|
|
const Monkey *m1 = a, *m2 = b;
|
|
if (m1->business < m2->business) return 1;
|
|
if (m1->business > m2->business) return -1;
|
|
return 0;
|
|
}
|
|
|
|
unsigned long calc_lcm(Monkey *monkeys, int count) {
|
|
unsigned long lcm = 1;
|
|
|
|
for (int m = 0; m < count; m++) {
|
|
unsigned long v = monkeys[m].test;
|
|
|
|
while (!(v % 2)) {
|
|
lcm *= 2;
|
|
v /= 2;
|
|
}
|
|
|
|
for (unsigned long i = 3; i <= sqrt(v); i += 3) {
|
|
while (!(v % i)) {
|
|
lcm *= i;
|
|
v /= i;
|
|
}
|
|
}
|
|
|
|
if (v > 2)
|
|
lcm *= v;
|
|
}
|
|
|
|
return lcm;
|
|
}
|
|
|
|
unsigned long monkey_business(Monkey *monkeys, int count, int steps, int part2) {
|
|
Monkey *copy = malloc(count * sizeof(Monkey));
|
|
memcpy(copy, monkeys, count * sizeof(Monkey));
|
|
monkeys = copy;
|
|
|
|
unsigned long lcm = part2 ? calc_lcm(monkeys, count) : 0;
|
|
|
|
for (int s = 0; s < steps; s++) {
|
|
for (int m = 0; m < count; m++) {
|
|
for (int j = 0; j < monkeys[m].count; j++) {
|
|
unsigned long new = monkeys[m].items[j],
|
|
val = monkeys[m].val;
|
|
if (!val) val = new;
|
|
monkeys[m].business++;
|
|
|
|
switch (monkeys[m].op) {
|
|
case '+': new += val; break;
|
|
case '*': new *= val; break;
|
|
}
|
|
|
|
new = part2 ? new % lcm : new / 3;
|
|
|
|
int target = monkeys[m].true;
|
|
if (new % monkeys[m].test)
|
|
target = monkeys[m].false;
|
|
|
|
monkeys[target].items[monkeys[target].count++] = new;
|
|
}
|
|
monkeys[m].count = 0;
|
|
}
|
|
}
|
|
|
|
qsort(monkeys, count, sizeof(Monkey), compar);
|
|
unsigned long result = monkeys[0].business * monkeys[1].business;
|
|
free(monkeys);
|
|
return result;
|
|
}
|
|
|
|
int main(void) {
|
|
Monkey monkeys[9] = {0};
|
|
int i = -1;
|
|
char buf[64], *p;
|
|
|
|
while (fgets(buf, 64, stdin)) {
|
|
if (*buf == 'M') {
|
|
i++;
|
|
} else {
|
|
switch (buf[2]) {
|
|
case 'S':
|
|
p = buf + 17;
|
|
do {
|
|
monkeys[i].items[monkeys[i].count] = atoi(++p);
|
|
monkeys[i].count++;
|
|
} while ((p = strchr(p, ',')));
|
|
break;
|
|
case 'O':
|
|
monkeys[i].op = buf[23];
|
|
monkeys[i].val = atoi(buf + 25);
|
|
break;
|
|
case 'T':
|
|
monkeys[i].test = atoi(buf + 21);
|
|
break;
|
|
case ' ':
|
|
if (buf[7] == 't')
|
|
monkeys[i].true = atoi(buf + 29);
|
|
else
|
|
monkeys[i].false = atoi(buf + 30);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
i++;
|
|
|
|
printf("Silver: %lu\nGold: %lu\n",
|
|
monkey_business(monkeys, i, 20, 0),
|
|
monkey_business(monkeys, i, 10000, 1));
|
|
}
|