1
0
Fork 0
Advent2021/Day 14/part1.cpp

125 lines
3.3 KiB
C++

#include <iostream>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
unordered_map<char, unsigned long long> get_count_after_reaction(unordered_map<string, char> reactions, string pair, int reaction_iterations);
int main(int argc, char* argv[])
{
string polymer;
getline(cin, polymer);
unordered_map<string, char> reactions;
string line;
getline(cin, line);
while(getline(cin, line))
{
reactions[line.substr(0,2)] = line[line.size()-1];
}
unordered_map<char, unsigned long long> counts;
for(int i = 0; i < polymer.size(); i++)
{
counts[polymer[i]] = 0;
}
for(int i = 0; i < polymer.size(); i++)
{
counts[polymer[i]]++;
}
for(int i = 0; i < polymer.size()-1; i++)
{
string pair = polymer.substr(i,2);
unordered_map<char, unsigned long long> pair_counts = get_count_after_reaction(reactions, pair, 10);
for(auto &it : pair_counts)
{
if (!counts.contains(it.first))
{
counts[it.first] = 0;
}
counts[it.first] += it.second;
}
}
vector<unsigned long long> counts_list;
for (auto &it : counts)
{
cout << it.first << " " << it.second << endl;
counts_list.push_back(it.second);
}
sort(counts_list.begin(), counts_list.end());
cout << counts_list[counts_list.size()-1]-counts_list[0] << endl;
}
unordered_map<char, unsigned long long> get_count_after_reaction(unordered_map<string, char> reactions, string pair, int reaction_iterations)
{
static unordered_map<string, vector<unordered_map<char, unsigned long long>>> reaction_cache;
if (0 == reaction_iterations)
{
return unordered_map<char, unsigned long long>();
}
if (!reaction_cache.contains(pair))
{
reaction_cache[pair] = vector<unordered_map<char, unsigned long long>>();
}
if (reaction_cache[pair].size() >= reaction_iterations)
{
if (reaction_cache[pair][reaction_iterations-1].size() != 0)
{
return reaction_cache[pair][reaction_iterations-1];
}
}
else
{
unsigned int old_size = reaction_cache[pair].size();
for (unsigned int current_size = old_size; current_size < reaction_iterations; current_size++)
{
reaction_cache[pair].push_back(unordered_map<char,unsigned long long>());
}
}
unordered_map<char, unsigned long long> out_counts;
out_counts[reactions[pair]] = 1;
string left_pair = pair.substr(0,1) + reactions[pair];
string right_pair = reactions[pair] + pair.substr(1,1);
unordered_map<char, unsigned long long> left_counts = get_count_after_reaction(reactions, left_pair, reaction_iterations-1);
unordered_map<char, unsigned long long> right_counts = get_count_after_reaction(reactions, right_pair, reaction_iterations-1);
for (auto &it : left_counts)
{
if (!out_counts.contains(it.first))
{
out_counts[it.first] = 0;
}
out_counts[it.first] += it.second;
}
for (auto &it : right_counts)
{
if (!out_counts.contains(it.first))
{
out_counts[it.first] = 0;
}
out_counts[it.first] += it.second;
}
reaction_cache[pair][reaction_iterations-1] = out_counts;
return out_counts;
}