From ed29df13cad00e2df307646d258310ce4f291ca0 Mon Sep 17 00:00:00 2001 From: zv0n Date: Sun, 11 Dec 2022 10:25:28 +0100 Subject: [PATCH] 11 --- 2022/11/Makefile | 16 +++++ 2022/11/input | 55 ++++++++++++++ 2022/11/main.cpp | 182 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 253 insertions(+) create mode 100644 2022/11/Makefile create mode 100644 2022/11/input create mode 100644 2022/11/main.cpp diff --git a/2022/11/Makefile b/2022/11/Makefile new file mode 100644 index 0000000..2a3c081 --- /dev/null +++ b/2022/11/Makefile @@ -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 diff --git a/2022/11/input b/2022/11/input new file mode 100644 index 0000000..0dd3bf4 --- /dev/null +++ b/2022/11/input @@ -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 diff --git a/2022/11/main.cpp b/2022/11/main.cpp new file mode 100644 index 0000000..aa92330 --- /dev/null +++ b/2022/11/main.cpp @@ -0,0 +1,182 @@ +#include +#include +#include +#include +#include + +class Monkey { + public: + Monkey( std::function worry_increase_function, + uint64_t divisor, + const std::deque &items, + const std::pair &target_monkeys ) + : worry_increase( worry_increase_function ), divisor( divisor ), + items( items ), target_monkeys( target_monkeys ) {} + // {target_monkey, worry_level} + std::pair 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 &getItems() { + return items; + } + + uint64_t getInspectedItems() { + return inspected_items; + } + + void setCommonDivisor(uint64_t divisor) { + common_divisor = divisor; + } + + private: + std::function worry_increase; + uint64_t divisor; + uint64_t common_divisor; + std::deque items; + const std::pair target_monkeys; + uint64_t inspected_items = 0; +}; + +std::vector getMonkeys( std::ifstream &file ) { + std::vector ret{}; + std::string tmp; + std::string str; + + std::function worry_increase; + uint64_t divisor; + uint64_t common_divisor = 1; + std::deque items; + std::pair 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 &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 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 &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 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; +}