This commit is contained in:
zv0n 2022-12-11 10:25:28 +01:00
parent 0303b2e9cd
commit ed29df13ca
3 changed files with 253 additions and 0 deletions

16
2022/11/Makefile Normal file
View File

@ -0,0 +1,16 @@
CXX ?= c++
CXXFLAGS ?= -std=c++11 -Wall -Wextra -pedantic -O2
PROJECT = monkeys
all: ${PROJECT}
${PROJECT}: main.cpp
${CXX} ${CXXFLAGS} -o $@ $^
test: ${PROJECT}
./${PROJECT}
clean:
${RM} *.o ${PROJECT}
.PHONY: all clean test

55
2022/11/input Normal file
View File

@ -0,0 +1,55 @@
Monkey 0:
Starting items: 80
Operation: new = old * 5
Test: divisible by 2
If true: throw to monkey 4
If false: throw to monkey 3
Monkey 1:
Starting items: 75, 83, 74
Operation: new = old + 7
Test: divisible by 7
If true: throw to monkey 5
If false: throw to monkey 6
Monkey 2:
Starting items: 86, 67, 61, 96, 52, 63, 73
Operation: new = old + 5
Test: divisible by 3
If true: throw to monkey 7
If false: throw to monkey 0
Monkey 3:
Starting items: 85, 83, 55, 85, 57, 70, 85, 52
Operation: new = old + 8
Test: divisible by 17
If true: throw to monkey 1
If false: throw to monkey 5
Monkey 4:
Starting items: 67, 75, 91, 72, 89
Operation: new = old + 4
Test: divisible by 11
If true: throw to monkey 3
If false: throw to monkey 1
Monkey 5:
Starting items: 66, 64, 68, 92, 68, 77
Operation: new = old * 2
Test: divisible by 19
If true: throw to monkey 6
If false: throw to monkey 2
Monkey 6:
Starting items: 97, 94, 79, 88
Operation: new = old * old
Test: divisible by 5
If true: throw to monkey 2
If false: throw to monkey 7
Monkey 7:
Starting items: 77, 85
Operation: new = old + 6
Test: divisible by 13
If true: throw to monkey 4
If false: throw to monkey 0

182
2022/11/main.cpp Normal file
View File

@ -0,0 +1,182 @@
#include <fstream>
#include <functional>
#include <iostream>
#include <sstream>
#include <vector>
class Monkey {
public:
Monkey( std::function<uint64_t( uint64_t )> worry_increase_function,
uint64_t divisor,
const std::deque<uint64_t> &items,
const std::pair<uint64_t, uint64_t> &target_monkeys )
: worry_increase( worry_increase_function ), divisor( divisor ),
items( items ), target_monkeys( target_monkeys ) {}
// {target_monkey, worry_level}
std::pair<uint64_t, uint64_t> performTurn(bool managable) {
inspected_items++;
auto worry = items.front();
items.pop_front();
worry = worry_increase( worry );
if(managable) {
worry /= 3;
}
worry = worry % common_divisor;
if ( worry % divisor == 0 ) {
return { target_monkeys.first, worry };
}
return { target_monkeys.second, worry };
}
void addWorry( uint64_t worry ) {
items.push_back( worry );
}
bool hasItems() {
return !items.empty();
}
const std::deque<uint64_t> &getItems() {
return items;
}
uint64_t getInspectedItems() {
return inspected_items;
}
void setCommonDivisor(uint64_t divisor) {
common_divisor = divisor;
}
private:
std::function<uint64_t( uint64_t )> worry_increase;
uint64_t divisor;
uint64_t common_divisor;
std::deque<uint64_t> items;
const std::pair<uint64_t, uint64_t> target_monkeys;
uint64_t inspected_items = 0;
};
std::vector<Monkey> getMonkeys( std::ifstream &file ) {
std::vector<Monkey> ret{};
std::string tmp;
std::string str;
std::function<uint64_t( uint64_t )> worry_increase;
uint64_t divisor;
uint64_t common_divisor = 1;
std::deque<uint64_t> items;
std::pair<uint64_t, uint64_t> target_monkeys;
while ( std::getline( file, str ) ) {
if ( str.empty() ) {
ret.emplace_back(worry_increase, divisor, items, target_monkeys);
items.clear();
}
std::stringstream ss( str );
ss >> tmp;
if(tmp == "Starting") {
ss >> tmp;
int tmp_i = 0;
ss >> tmp_i;
items.push_back(tmp_i);
while(ss.peek() == ',') {
ss >> tmp;
ss >> tmp_i;
items.push_back(tmp_i);
}
} else if(tmp == "Operation:") {
ss >> tmp; // new
ss >> tmp; // =
ss >> tmp; // old
char op = 0;
uint64_t parameter = 0;
ss >> op;
ss.get();
if(ss.peek() == 'o') {
if(op == '+') {
worry_increase = [](uint64_t old) {return old + old;};
} else {
worry_increase = [](uint64_t old) {return old * old;};
}
} else {
ss >> parameter;
if(op == '+') {
worry_increase = [parameter](uint64_t old) {return old + parameter;};
} else {
worry_increase = [parameter](uint64_t old) {return old * parameter;};
}
}
} else if(tmp == "Test:") {
ss >> tmp; // divisible
ss >> tmp; // by
ss >> divisor;
common_divisor *= divisor;
} else if(tmp == "If") {
std::string bool_val;
ss >> bool_val;
ss >> tmp; // throw
ss >> tmp; // to
ss >> tmp; // monkey
int monkey_index = 0;
ss >> monkey_index;
if(bool_val == "true:") {
target_monkeys.first = monkey_index;
} else {
target_monkeys.second = monkey_index;
}
}
}
ret.emplace_back(worry_increase, divisor, items, target_monkeys);
for(auto &monkey : ret) {
monkey.setCommonDivisor(common_divisor);
}
return ret;
}
uint64_t part1(const std::vector<Monkey> &input) {
auto monkeys = input;
for(int i = 0; i < 20; i++) {
for(auto &monkey : monkeys) {
while(monkey.hasItems()) {
auto monkey_throw = monkey.performTurn(true);
monkeys[monkey_throw.first].addWorry(monkey_throw.second);
}
}
}
std::vector<uint64_t> inspected_items{};
for(auto &monkey : monkeys) {
inspected_items.push_back(monkey.getInspectedItems());
}
std::sort(inspected_items.begin(), inspected_items.end());
return inspected_items[inspected_items.size() - 1] * inspected_items[inspected_items.size() - 2];
}
uint64_t part2(const std::vector<Monkey> &input) {
auto monkeys = input;
for(int i = 1; i <= 10000; i++) {
for(auto &monkey : monkeys) {
while(monkey.hasItems()) {
auto monkey_throw = monkey.performTurn(false);
monkeys[monkey_throw.first].addWorry(monkey_throw.second);
}
}
}
std::vector<uint64_t> inspected_items{};
size_t i = 0;
for(auto &monkey : monkeys) {
inspected_items.push_back(monkey.getInspectedItems());
i++;
}
std::sort(inspected_items.begin(), inspected_items.end());
return inspected_items[inspected_items.size() - 1] * inspected_items[inspected_items.size() - 2];
}
int main() {
std::ifstream input_file( "input" );
auto monkeys = getMonkeys( input_file );
std::cout << "Monkey business after 20 rounds when you don't worry is \033[91;1m" << part1(monkeys) << "\033[0m."
<< std::endl;
std::cout << "Monkey business after 10000 rounds when you worry a lot is \033[91;1m" << part2(monkeys) << "\033[0m."
<< std::endl;
}