#include #include #include #define BUFFER_SIZE 64 #define MONKEY_MAX_STASH 100 #define substitute(w, o) (o == 0 ? w : o) enum stage { INIT, ITEM_COUNT, ITEMS, OPERATION, TEST, THROW_TRUE, THROW_FALSE }; typedef struct monkey { unsigned long stash[MONKEY_MAX_STASH]; unsigned long stash_size; int test; int throw_true; int throw_false; int operation[3]; unsigned long throw_count; } MONKEY; unsigned long operate(unsigned long, int*); int main() { char buf[BUFFER_SIZE], *p, c; memset(buf, 0, BUFFER_SIZE); p = buf; enum stage currentStage = INIT; MONKEY *monkeys, *currentMonkey; int monkeyCount, itemRemaining; while ((c = getchar()) != EOF) { *p++ = c; if (c == '\n') { switch (currentStage) { case INIT: sscanf(buf, "%i", &monkeyCount); monkeys = (MONKEY*)malloc(monkeyCount*sizeof(MONKEY)); memset(monkeys, 0, monkeyCount*sizeof(MONKEY)); currentMonkey = monkeys; currentStage = ITEM_COUNT; break; case ITEM_COUNT: sscanf(buf, "%i", &itemRemaining); currentStage = ITEMS; break; case ITEMS: sscanf(buf, "%lu", ¤tMonkey->stash[currentMonkey->stash_size]); currentMonkey->stash_size++; itemRemaining--; if (itemRemaining == 0) { currentStage = OPERATION; } break; case OPERATION: sscanf(buf, "%i %i %i", ¤tMonkey->operation[0], ¤tMonkey->operation[1], ¤tMonkey->operation[2]); currentStage = TEST; break; case TEST: sscanf(buf, "%i", ¤tMonkey->test); currentStage = THROW_TRUE; break; case THROW_TRUE: sscanf(buf, "%i", ¤tMonkey->throw_true); currentStage = THROW_FALSE; break; case THROW_FALSE: sscanf(buf, "%i", ¤tMonkey->throw_false); currentMonkey++; currentStage = ITEM_COUNT; break; } memset(buf, 0, BUFFER_SIZE); p = buf; } } unsigned long simplifier = 1; for (int j = 0; j < monkeyCount; j++) { simplifier *= monkeys[j].test; } unsigned long worry, sumItems; // Play 20 rounds with tha monkeys for (int i = 0; i < 10000; i++) { sumItems = 0; // Each monkeys for (int j = 0; j < monkeyCount; j++) { // Each item for (int k = 0; k < monkeys[j].stash_size; k++) { monkeys[j].throw_count++; worry = monkeys[j].stash[k]; worry = operate(worry, monkeys[j].operation); // Don't you worry child // worry /= 3; if (worry % monkeys[j].test == 0) { monkeys[monkeys[j].throw_true].stash[monkeys[monkeys[j].throw_true].stash_size] = worry % simplifier; monkeys[monkeys[j].throw_true].stash_size++; } else { monkeys[monkeys[j].throw_false].stash[monkeys[monkeys[j].throw_false].stash_size] = worry % simplifier; monkeys[monkeys[j].throw_false].stash_size++; } } monkeys[j].stash_size = 0; memset(monkeys[j].stash, 0, MONKEY_MAX_STASH*sizeof(unsigned long)); } // Everything was thrown } unsigned long max1 = 0, max2 = 0; for (int i = 0; i < monkeyCount; i++) { if (monkeys[i].throw_count > max1) { max2 = max1; max1 = monkeys[i].throw_count; } else if (monkeys[i].throw_count > max2) { max2 = monkeys[i].throw_count; } printf("Monkey %i throw count: %lu\n", i, monkeys[i].throw_count); } printf("\nMonkey business: %lu\n", max1 * max2); free(monkeys); } unsigned long operate(unsigned long worry, int* operation) { if (operation[1] == 0) { return substitute(worry, operation[0]) + substitute(worry, operation[2]); } else if (operation[1] == 1) { return substitute(worry, operation[0]) * substitute(worry, operation[2]); } return -1; }