#include #include #include #include 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)); }