Day21
This commit is contained in:
1677
day21/input.txt
Normal file
1677
day21/input.txt
Normal file
File diff suppressed because it is too large
Load Diff
BIN
day21/monkeysagain
Executable file
BIN
day21/monkeysagain
Executable file
Binary file not shown.
162
day21/monkeysagain.c
Normal file
162
day21/monkeysagain.c
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user