Files
contests/advent_of_code/2021/d6/main.cpp

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;
}