Files
Dobos Ádám c75abf3ea1 Day11
2022-12-12 01:31:28 +01:00

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", &currentMonkey->stash[currentMonkey->stash_size]);
currentMonkey->stash_size++;
itemRemaining--;
if (itemRemaining == 0) {
currentStage = OPERATION;
}
break;
case OPERATION:
sscanf(buf, "%i %i %i", &currentMonkey->operation[0], &currentMonkey->operation[1], &currentMonkey->operation[2]);
currentStage = TEST;
break;
case TEST:
sscanf(buf, "%i", &currentMonkey->test);
currentStage = THROW_TRUE;
break;
case THROW_TRUE:
sscanf(buf, "%i", &currentMonkey->throw_true);
currentStage = THROW_FALSE;
break;
case THROW_FALSE:
sscanf(buf, "%i", &currentMonkey->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;
}