Files
dobiadi 499e5034d0 Day21
2022-12-23 16:26:16 +01:00

163 lines
5.6 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#define BUFFER_SIZE 64
#define MAX_MONKEYS 4096
enum monkeyType {
CONSTANT,
ARITHMETIC
};
enum operand {
ADDITION,
SUBTRACTION,
MULTIPLICATION,
DIVISION
};
typedef struct monkey {
char name[4];
char leftOperandName[4];
char rightOperandName[4];
enum monkeyType type;
struct monkey *leftOperand;
struct monkey *rightOperand;
enum operand op;
long long number;
int hasValue;
} MONKEY;
long long getNumber(MONKEY);
int main() {
char buf[BUFFER_SIZE], *p, c;
memset(buf, 0, BUFFER_SIZE);
p = buf;
MONKEY monkeys[MAX_MONKEYS], root;
memset(monkeys, 0, MAX_MONKEYS * sizeof(MONKEY));
int monkey_count = 0;
char op;
while ((c = getchar()) != EOF) {
*p++ = c;
if (c == '\n') {
if (sscanf(buf, "%c%c%c%c: %c%c%c%c %c %c%c%c%c", &monkeys[monkey_count].name[0], &monkeys[monkey_count].name[1], &monkeys[monkey_count].name[2], &monkeys[monkey_count].name[3], &monkeys[monkey_count].leftOperandName[0], &monkeys[monkey_count].leftOperandName[1], &monkeys[monkey_count].leftOperandName[2], &monkeys[monkey_count].leftOperandName[3], &op, &monkeys[monkey_count].rightOperandName[0], &monkeys[monkey_count].rightOperandName[1], &monkeys[monkey_count].rightOperandName[2], &monkeys[monkey_count].rightOperandName[3]) == 13) {
switch (op) {
case '+':
monkeys[monkey_count].op = ADDITION;
break;
case '-':
monkeys[monkey_count].op = SUBTRACTION;
break;
case '*':
monkeys[monkey_count].op = MULTIPLICATION;
break;
case '/':
monkeys[monkey_count].op = DIVISION;
break;
}
monkeys[monkey_count].type = ARITHMETIC;
} else {
sscanf(buf, "%c%c%c%c: %lli", &monkeys[monkey_count].name[0], &monkeys[monkey_count].name[1], &monkeys[monkey_count].name[2], &monkeys[monkey_count].name[3], &monkeys[monkey_count].number);
monkeys[monkey_count].type = CONSTANT;
monkeys[monkey_count].hasValue = 1;
}
monkey_count++;
memset(buf, 0, BUFFER_SIZE);
p = buf;
}
}
// Change names to pointers in monkeys
for (int i = 0; i < monkey_count; i++) {
if (monkeys[i].type == ARITHMETIC) {
for (int j = 0; j < monkey_count; j++) {
if (monkeys[i].leftOperandName[0] == monkeys[j].name[0] && monkeys[i].leftOperandName[1] == monkeys[j].name[1] && monkeys[i].leftOperandName[2] == monkeys[j].name[2] && monkeys[i].leftOperandName[3] == monkeys[j].name[3]) {
monkeys[i].leftOperand = &monkeys[j];
}
if (monkeys[i].rightOperandName[0] == monkeys[j].name[0] && monkeys[i].rightOperandName[1] == monkeys[j].name[1] && monkeys[i].rightOperandName[2] == monkeys[j].name[2] && monkeys[i].rightOperandName[3] == monkeys[j].name[3]) {
monkeys[i].rightOperand = &monkeys[j];
}
}
}
}
// Get the shouted number
//
// Find 'root'
for (int i = 0; i < monkey_count; i++) {
if (monkeys[i].name[0] == 'r' && monkeys[i].name[1] == 'o' && monkeys[i].name[2] == 'o' && monkeys[i].name[3] == 't') {\
root = monkeys[i];
}
}
printf("%lli\n", getNumber(root));
// Good old bruteforce for part 2
// Find human
MONKEY *human;
for (int i = 0; i < monkey_count; i++) {
if (monkeys[i].name[0] == 'h' && monkeys[i].name[1] == 'u' && monkeys[i].name[2] == 'm' && monkeys[i].name[3] == 'n') {\
human = &monkeys[i];
}
}
long long myNumber = 3759566892641;
human->hasValue = 1;
human->type = CONSTANT;
human->number = myNumber;
int found = 0;
printf("%lli, %lli\n", getNumber(*root.leftOperand), getNumber(*root.rightOperand));
printf("%lli\n", myNumber);
// do {
// // Reset all arithmetic monkeys
// for (int i = 0; i < monkey_count; i++) {
// if (monkeys[i].type == ARITHMETIC) {
// monkeys[i].hasValue = 0;
// }
// }
// human->number = myNumber++;
// long long left = getNumber(*root.leftOperand);
// // Reset all arithmetic monkeys
// for (int i = 0; i < monkey_count; i++) {
// if (monkeys[i].type == ARITHMETIC) {
// monkeys[i].hasValue = 0;
// }
// }
// long long right = getNumber(*root.rightOperand);
//
// found = left == right;
// } while (!found);
//
// printf("%lli\n", myNumber-1);
}
long long getNumber(MONKEY monkey) {
// If previuosly calculated or constant
if (monkey.hasValue == 1) {
return monkey.number;
}
long long result = 0;
switch (monkey.op) {
case ADDITION:
result = getNumber(*monkey.leftOperand) + getNumber(*monkey.rightOperand);
break;
case SUBTRACTION:
result = getNumber(*monkey.leftOperand) - getNumber(*monkey.rightOperand);
break;
case MULTIPLICATION:
result = getNumber(*monkey.leftOperand) * getNumber(*monkey.rightOperand);
break;
case DIVISION:
result = getNumber(*monkey.leftOperand) / getNumber(*monkey.rightOperand);
break;
}
monkey.hasValue = 1;
monkey.number = result;
return result;
}