|
|
|
#define OLC_PGE_APPLICATION
|
|
|
|
#include "pixelGameEngine.h"
|
|
|
|
#include "olcutils.h"
|
|
|
|
#include "InfInt.h"
|
|
|
|
|
|
|
|
using namespace olc;
|
|
|
|
|
|
|
|
|
|
|
|
//Break down each number into its raw factors.
|
|
|
|
//The number itself is also stored.
|
|
|
|
//If the factorization is larger than 19, we can discard it. It shouldn't matter.
|
|
|
|
|
|
|
|
std::vector<int>factor(int numb){
|
|
|
|
std::vector<int>factors;
|
|
|
|
while (numb>1){
|
|
|
|
for (int i=2;i<numb;i++){
|
|
|
|
if (numb%i==0){
|
|
|
|
factors.push_back(i);
|
|
|
|
numb/=i;
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factors.push_back(numb);
|
|
|
|
numb/=numb;
|
|
|
|
next:;
|
|
|
|
}
|
|
|
|
factors.push_back(1);
|
|
|
|
return factors;
|
|
|
|
}
|
|
|
|
|
|
|
|
struct factorNumber{
|
|
|
|
void SetupOffsets(int initial){
|
|
|
|
offsets.push_back({23,0});
|
|
|
|
offsets.push_back({19,0});
|
|
|
|
offsets.push_back({13,0});
|
|
|
|
offsets.push_back({17,0});
|
|
|
|
for (int i=0;i<offsets.size();i++){
|
|
|
|
offsets[i].second=initial%offsets[i].first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::vector<std::pair<int,int>>factors;
|
|
|
|
std::vector<std::pair<int,int>>offsets;
|
|
|
|
factorNumber(int numb){
|
|
|
|
SetupOffsets(numb);
|
|
|
|
std::vector<int>tmp=factor(numb);
|
|
|
|
for (int j=0;j<tmp.size();j++){
|
|
|
|
for (int i=0;i<factors.size();i++){
|
|
|
|
if (factors[i].first==tmp[j]){
|
|
|
|
factors[i].second++;
|
|
|
|
goto nextfactor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factors.push_back({tmp[j],1});
|
|
|
|
nextfactor:;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factorNumber&operator=(int numb){
|
|
|
|
factors.clear();
|
|
|
|
offsets.clear();
|
|
|
|
SetupOffsets(numb);
|
|
|
|
std::vector<int>tmp=factor(numb);
|
|
|
|
for (int j=0;j<tmp.size();j++){
|
|
|
|
for (int i=0;i<factors.size();i++){
|
|
|
|
if (factors[i].first==tmp[j]){
|
|
|
|
factors[i].second++;
|
|
|
|
goto nextfactor;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
factors.push_back({tmp[j],1});
|
|
|
|
nextfactor:;
|
|
|
|
}
|
|
|
|
return*this;
|
|
|
|
}
|
|
|
|
factorNumber&operator+=(int numb){
|
|
|
|
for (int i=0;i<offsets.size();i++){
|
|
|
|
std::pair<int,int>&offset=offsets[i];
|
|
|
|
for (int j=0;j<factors.size();j++){
|
|
|
|
if (factors[j].first==offset.first){
|
|
|
|
factors[j].second+=(offset.second+numb)/offset.first;
|
|
|
|
goto addOffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
addOffset:
|
|
|
|
offset.second=(offset.second+numb)%offset.first;
|
|
|
|
}
|
|
|
|
return*this;
|
|
|
|
}
|
|
|
|
factorNumber&operator*=(int numb){
|
|
|
|
std::vector<int>factors=factor(numb);
|
|
|
|
for (int i=0;i<factors.size();i++){
|
|
|
|
for (int j=0;j<this->factors.size();j++){
|
|
|
|
if (this->factors[j].first==factors[i]){
|
|
|
|
this->factors[j].second++;
|
|
|
|
goto gonext;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
this->factors.push_back({factors[i],1});
|
|
|
|
gonext:;
|
|
|
|
}
|
|
|
|
return*this;
|
|
|
|
}
|
|
|
|
int operator%(int numb){
|
|
|
|
for (int i=0;i<offsets.size();i++){
|
|
|
|
if (offsets[i].first==numb){
|
|
|
|
return offsets[i].second;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int j=0;j<factors.size();j++){
|
|
|
|
if (factors[j].first!=1&&(factors[j].first==numb||factors[j].second%numb==0)){
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
std::cout<<"No divisibility information for modulus "<<numb<<" !! THIS SHOULDN'T BE HAPPENING !!"<<std::endl;
|
|
|
|
return -1; //This shouldn't happen??
|
|
|
|
}
|
|
|
|
friend std::ostream&operator<<(std::ostream&out,factorNumber&rhs){
|
|
|
|
out<<"Factors:"<<std::endl;
|
|
|
|
for (int i=0;i<rhs.factors.size();i++){
|
|
|
|
out<<" "<<rhs.factors[i].first<<" x"<<rhs.factors[i].second<<std::endl;
|
|
|
|
}
|
|
|
|
std::cout<<"Offsets:"<<std::endl;
|
|
|
|
for (int i=0;i<rhs.offsets.size();i++){
|
|
|
|
out<<" "<<rhs.offsets[i].first<<": "<<rhs.offsets[i].second<<std::endl;
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct Monkey{
|
|
|
|
std::vector<factorNumber> items;
|
|
|
|
char operation;
|
|
|
|
int operation_amt;
|
|
|
|
int divisible;
|
|
|
|
int trueThrow;
|
|
|
|
int falseThrow;
|
|
|
|
int inspAmt;
|
|
|
|
};
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
std::vector<Monkey> monkeys;
|
|
|
|
std::ifstream file("input");
|
|
|
|
|
|
|
|
/*monkeys.push_back({{89,95,92,64,87,68},'*',11,2,7,4});
|
|
|
|
monkeys.push_back({{87,67},'+',1,13,3,6});
|
|
|
|
monkeys.push_back({{95, 79, 92, 82, 60},'+',6,3,1,6});
|
|
|
|
monkeys.push_back({{67, 97, 56},'*',-1,17,7,0});
|
|
|
|
monkeys.push_back({{80, 68, 87, 94, 61, 59, 50, 68},'*',7,19,5,2});
|
|
|
|
monkeys.push_back({{73, 51, 76, 59},'+',8,7,2,1});
|
|
|
|
monkeys.push_back({{92},'+',5,11,3,0});
|
|
|
|
monkeys.push_back({{99, 76, 78, 76, 79, 90, 89},'+',7,5,4,5});*/
|
|
|
|
monkeys.push_back({{79,98},'*',19,23,2,3});
|
|
|
|
monkeys.push_back({{54, 65, 75, 74},'+',6,19,2,0});
|
|
|
|
monkeys.push_back({{79, 60, 97},'*',-1,13,1,3});
|
|
|
|
monkeys.push_back({{74},'+',3,17,0,1});
|
|
|
|
|
|
|
|
/*
|
|
|
|
factorNumber test(17);
|
|
|
|
|
|
|
|
test=84075;
|
|
|
|
for (int i=0;i<77;i++){
|
|
|
|
test*=23;
|
|
|
|
}
|
|
|
|
std::cout<<test<<std::endl;
|
|
|
|
std::cout<<test%59<<std::endl;
|
|
|
|
std::cout<<test%19<<std::endl;
|
|
|
|
std::cout<<test%23<<std::endl;
|
|
|
|
std::cout<<test%13<<std::endl;
|
|
|
|
std::cout<<test%17<<std::endl;*/
|
|
|
|
|
|
|
|
for (int round=0;round<10000;round++){
|
|
|
|
for (int i=0;i<monkeys.size();i++){
|
|
|
|
Monkey&m=monkeys[i];
|
|
|
|
m.inspAmt+=m.items.size();
|
|
|
|
for (int j=0;j<m.items.size();j++){
|
|
|
|
factorNumber worryLevel=m.items[j];
|
|
|
|
//std::cout<<worryLevel<<std::endl;
|
|
|
|
if (m.operation=='+'){
|
|
|
|
if (m.operation_amt!=-1){
|
|
|
|
worryLevel+=m.operation_amt;
|
|
|
|
} else {
|
|
|
|
worryLevel*=2;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (m.operation_amt!=-1){
|
|
|
|
worryLevel*=m.operation_amt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (worryLevel%m.divisible==0){
|
|
|
|
Monkey&newMonkey=monkeys[m.trueThrow];
|
|
|
|
newMonkey.items.push_back(worryLevel);
|
|
|
|
m.items.erase(m.items.begin());
|
|
|
|
j--;
|
|
|
|
} else {
|
|
|
|
Monkey&newMonkey=monkeys[m.falseThrow];
|
|
|
|
newMonkey.items.push_back(worryLevel);
|
|
|
|
m.items.erase(m.items.begin());
|
|
|
|
j--;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (round==19||round==0||(round+1)%1000==0){
|
|
|
|
std::cout<<"Round "<<(round+1)<<"..."<<std::endl;
|
|
|
|
for (int i=0;i<monkeys.size();i++){
|
|
|
|
Monkey&m=monkeys[i];
|
|
|
|
std::cout<<" Monkey "<<i<<": "<<m.inspAmt<<" inspected"<<std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::sort(monkeys.begin(),monkeys.end(),[](Monkey&first,Monkey&second){return second.inspAmt<first.inspAmt;});
|
|
|
|
for (int i=0;i<monkeys.size();i++){
|
|
|
|
Monkey&m=monkeys[i];
|
|
|
|
std::cout<<"Monkey "<<i<<": "<<m.inspAmt<<" inspections"<<std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::cout<<((long)monkeys[0].inspAmt*(long)monkeys[1].inspAmt)<<std::endl;
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|