145 lines
4.5 KiB
C
145 lines
4.5 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#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;
|
|
}
|