11
This commit is contained in:
parent
0303b2e9cd
commit
ed29df13ca
16
2022/11/Makefile
Normal file
16
2022/11/Makefile
Normal 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
55
2022/11/input
Normal 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
182
2022/11/main.cpp
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user