111 lines
3.5 KiB
C++
111 lines
3.5 KiB
C++
#include <bits/stdc++.h>
|
|
|
|
using namespace std;
|
|
|
|
typedef unsigned long long ll;
|
|
|
|
size_t reproduction(int stage, int days){
|
|
vector<int> fishies(1, stage);
|
|
vector<int> new_fishies;
|
|
|
|
for(int i = 0; i < days; ++i){
|
|
new_fishies.clear();
|
|
|
|
for(auto& fishie : fishies){
|
|
if(fishie == 0){
|
|
new_fishies.push_back(6);
|
|
new_fishies.push_back(8);
|
|
} else{
|
|
new_fishies.push_back(--fishie);
|
|
}
|
|
}
|
|
|
|
fishies.clear();
|
|
fishies = new_fishies;
|
|
|
|
// cout << "Day " << i << ": ";
|
|
// for(auto fishie : new_fishies){
|
|
// cout << fishie << " ";
|
|
// } cout << endl;
|
|
}
|
|
|
|
return fishies.size();
|
|
}
|
|
|
|
ll smart_reproduce(int days, const array<ll, 9> &start){
|
|
array<ll, 9> old_fishies = start;
|
|
array<ll, 9> new_fishies;
|
|
|
|
while(days > 0){
|
|
for(size_t i = 0; i < old_fishies.size(); ++i){
|
|
if(i == 8){
|
|
new_fishies[i] = old_fishies[0];
|
|
} else if(i == 6){
|
|
new_fishies[i] = old_fishies[i + 1] + old_fishies[0];
|
|
} else{
|
|
new_fishies[i] = old_fishies[i + 1];
|
|
}
|
|
}
|
|
|
|
old_fishies = new_fishies;
|
|
days--;
|
|
}
|
|
|
|
ll result = 0;
|
|
for(auto &fishie : old_fishies){
|
|
result += fishie;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
int main(){
|
|
ios::sync_with_stdio(0);
|
|
cin.tie(0);
|
|
|
|
vector<int> input_fishies = {5,1,1,3,1,1,5,1,2,1,5,2,5,1,1,1,4,1,1,5,1,1,4,1,1,1,3,5,1,1,1,1,1,1,1,1,1,4,4,4,1,1,1,1,1,4,1,1,1,1,1,5,1,1,1,4,1,1,1,1,1,3,1,1,4,1,4,1,1,2,3,1,1,1,1,4,1,2,2,1,1,1,1,1,1,3,1,1,1,1,1,2,1,1,1,1,1,1,1,4,4,1,4,2,1,1,1,1,1,4,3,1,1,1,1,2,1,1,1,2,1,1,3,1,1,1,2,1,1,1,3,1,3,1,1,1,1,1,1,1,1,1,3,1,1,1,1,3,1,1,1,1,1,1,2,1,1,2,3,1,2,1,1,4,1,1,5,3,1,1,1,2,4,1,1,2,4,2,1,1,1,1,1,1,1,2,1,1,1,1,1,1,1,1,4,3,1,2,1,2,1,5,1,2,1,1,5,1,1,1,1,1,1,2,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1,3,1,1,5,1,1,1,1,5,1,4,1,1,1,4,1,3,4,1,4,1,1,1,1,1,1,1,1,1,3,5,1,3,1,1,1,1,4,1,5,3,1,1,1,1,1,5,1,1,1,2,2};
|
|
// vector<int> input_fishies = {3,4,3,1,2};
|
|
array<ll, 9> reproduction_numbers;
|
|
reproduction_numbers.fill(0);
|
|
|
|
ll result = 0;
|
|
for(auto &fishie : input_fishies){
|
|
if(reproduction_numbers[fishie] == 0){
|
|
int rn = reproduction(fishie, 80);
|
|
result += rn;
|
|
reproduction_numbers[fishie] = rn;
|
|
} else{
|
|
result += reproduction_numbers[fishie];
|
|
}
|
|
}
|
|
|
|
cout << result << endl;
|
|
|
|
// Now do the exact same but with a bigger number of days
|
|
|
|
// Ok this doesn't really work out, it uses up too much memory, prolly because it's pretty exponential
|
|
// So it's probably better to do this with a bottoms up approach
|
|
|
|
// Doing a problem analysis with example I came to the conclusion that you only need to calculate one
|
|
// starting point, with 0 then being the obvious choice. The rest can be derived from that
|
|
|
|
// Also, I realized that instead of keeping track of all lanternfish numbers in a vector,
|
|
// I can just use a map or array or vector tracking the number of fishes with the index indicating the stage
|
|
// This reduces the memory size drastically, while still being just iterative
|
|
|
|
// First let's test the new method: works just dandy
|
|
// Only problem now is overflows I think
|
|
|
|
array<ll, 9> start = {0, };
|
|
for(auto &fish : input_fishies){
|
|
start[fish]++;
|
|
}
|
|
|
|
result = smart_reproduce(256, start);
|
|
|
|
cout << result << endl;
|
|
|
|
cout << flush;
|
|
|
|
return 0;
|
|
} |