Compare commits
4 Commits
27cedade38
...
14453cba1f
Author | SHA1 | Date |
---|---|---|
|
14453cba1f | |
|
aa4a1076a2 | |
|
c432d3f381 | |
|
426e2f5001 |
|
@ -1 +1,3 @@
|
|||
.vscode
|
||||
*/*
|
||||
!**/*.cpp
|
|
@ -0,0 +1,112 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
constexpr int grid_size{10};
|
||||
int grid[grid_size][grid_size] = {0};
|
||||
|
||||
void output_grid();
|
||||
|
||||
std::ostream& bold_on(std::ostream& os);
|
||||
std::ostream& bold_off(std::ostream& os);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
string line = "";
|
||||
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
getline(cin, line);
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
grid[x][y] = (int)(line[x]-'0');
|
||||
}
|
||||
}
|
||||
|
||||
int total_flashes = 0;
|
||||
for (int t = 0; t < 100; t++)
|
||||
{
|
||||
//Step 1, increment
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
++grid[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
//Step 2, flash
|
||||
bool flashed[grid_size][grid_size] = {false};
|
||||
bool flash_occurred = false;
|
||||
do
|
||||
{
|
||||
flash_occurred = false;
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
if (!flashed[x][y] && grid[x][y] > 9)
|
||||
{
|
||||
flashed[x][y] = true;
|
||||
flash_occurred = true;
|
||||
++total_flashes;
|
||||
|
||||
for(int fy = max(0,y-1); fy < min(grid_size, y+2); fy++)
|
||||
{
|
||||
for(int fx = max(0,x-1); fx < min(grid_size,x+2); fx++)
|
||||
{
|
||||
grid[fx][fy]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (flash_occurred);
|
||||
|
||||
//Step 3, flashed are cleared
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
if (flashed[x][y])
|
||||
{
|
||||
grid[x][y] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cout << total_flashes << endl;
|
||||
}
|
||||
|
||||
void output_grid()
|
||||
{
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
if (0 == grid[x][y])
|
||||
{
|
||||
cout << bold_on << grid[x][y] << bold_off;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << grid[x][y];
|
||||
}
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
std::ostream& bold_on(std::ostream& os)
|
||||
{
|
||||
return os << "\e[1m";
|
||||
}
|
||||
|
||||
std::ostream& bold_off(std::ostream& os)
|
||||
{
|
||||
return os << "\e[0m";
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
constexpr int grid_size{10};
|
||||
int grid[grid_size][grid_size] = {0};
|
||||
|
||||
void output_grid();
|
||||
|
||||
std::ostream& bold_on(std::ostream& os);
|
||||
std::ostream& bold_off(std::ostream& os);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
string line = "";
|
||||
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
getline(cin, line);
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
grid[x][y] = (int)(line[x]-'0');
|
||||
}
|
||||
}
|
||||
|
||||
int t = 0;
|
||||
bool all_flashed = false;
|
||||
while(!all_flashed)
|
||||
{
|
||||
all_flashed = true;
|
||||
//Step 1, increment
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
++grid[x][y];
|
||||
}
|
||||
}
|
||||
|
||||
//Step 2, flash
|
||||
bool flashed[grid_size][grid_size] = {false};
|
||||
bool flash_occurred = false;
|
||||
do
|
||||
{
|
||||
flash_occurred = false;
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
if (!flashed[x][y] && grid[x][y] > 9)
|
||||
{
|
||||
flashed[x][y] = true;
|
||||
flash_occurred = true;
|
||||
|
||||
for(int fy = max(0,y-1); fy < min(grid_size, y+2); fy++)
|
||||
{
|
||||
for(int fx = max(0,x-1); fx < min(grid_size,x+2); fx++)
|
||||
{
|
||||
grid[fx][fy]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (flash_occurred);
|
||||
|
||||
//Step 3, flashed are cleared
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
if (flashed[x][y])
|
||||
{
|
||||
grid[x][y] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
all_flashed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
t++;
|
||||
}
|
||||
|
||||
cout << t << endl;
|
||||
}
|
||||
|
||||
void output_grid()
|
||||
{
|
||||
for (int y = 0; y < grid_size; y++)
|
||||
{
|
||||
for (int x = 0; x < grid_size; x++)
|
||||
{
|
||||
if (0 == grid[x][y])
|
||||
{
|
||||
cout << bold_on << grid[x][y] << bold_off;
|
||||
}
|
||||
else
|
||||
{
|
||||
cout << grid[x][y];
|
||||
}
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
std::ostream& bold_on(std::ostream& os)
|
||||
{
|
||||
return os << "\e[1m";
|
||||
}
|
||||
|
||||
std::ostream& bold_off(std::ostream& os)
|
||||
{
|
||||
return os << "\e[0m";
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string start = "start";
|
||||
string finish = "end";
|
||||
|
||||
string lowercase = "qwertyuiopasdfghjklzxcvbnm";
|
||||
|
||||
int find_all_paths(unordered_map<string, set<string>> graph, vector<string> current_path);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
unordered_map<string, set<string>> graph;
|
||||
|
||||
string line;
|
||||
while(getline(cin, line))
|
||||
{
|
||||
string::size_type n = line.find("-",0);
|
||||
string node1 = line.substr(0,n);
|
||||
string node2 = line.substr(n+1);
|
||||
|
||||
if (!graph.contains(node1))
|
||||
{
|
||||
graph.emplace(node1, set<string>());
|
||||
}
|
||||
|
||||
if (!graph.contains(node2))
|
||||
{
|
||||
graph.emplace(node2, set<string>());
|
||||
}
|
||||
|
||||
graph[node1].insert(node2);
|
||||
graph[node2].insert(node1);
|
||||
}
|
||||
|
||||
vector<string> beginning_path;
|
||||
beginning_path.push_back(start);
|
||||
|
||||
cout << find_all_paths(graph, beginning_path) << endl;
|
||||
}
|
||||
|
||||
int find_all_paths(unordered_map<string, set<string>> graph, vector<string> current_path)
|
||||
{
|
||||
int found_paths = 0;
|
||||
set<string> connected_nodes = graph[current_path.back()];
|
||||
|
||||
for (set<string>::iterator it = connected_nodes.begin(); it != connected_nodes.end(); ++it)
|
||||
{
|
||||
string current_node = *it;
|
||||
|
||||
if (current_node.compare(finish) == 0)
|
||||
{
|
||||
++found_paths;
|
||||
}
|
||||
else if (string::npos == current_node.find_first_of(lowercase) ||
|
||||
current_path.end() == std::find(current_path.begin(), current_path.end(), current_node))
|
||||
{ //Big cave or small cave not in path
|
||||
vector<string> next_path(current_path);
|
||||
next_path.push_back(current_node);
|
||||
found_paths += find_all_paths(graph, next_path);
|
||||
}
|
||||
}
|
||||
|
||||
return found_paths;
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
#include <iostream>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string start = "start";
|
||||
string finish = "end";
|
||||
|
||||
string lowercase = "qwertyuiopasdfghjklzxcvbnm";
|
||||
|
||||
int find_all_paths(unordered_map<string, set<string>> graph, vector<string> current_path, bool double_small_taken);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
unordered_map<string, set<string>> graph;
|
||||
|
||||
string line;
|
||||
while(getline(cin, line))
|
||||
{
|
||||
string::size_type n = line.find("-",0);
|
||||
string node1 = line.substr(0,n);
|
||||
string node2 = line.substr(n+1);
|
||||
|
||||
if (!graph.contains(node1))
|
||||
{
|
||||
graph.emplace(node1, set<string>());
|
||||
}
|
||||
|
||||
if (!graph.contains(node2))
|
||||
{
|
||||
graph.emplace(node2, set<string>());
|
||||
}
|
||||
|
||||
if (0 != node2.compare(start))
|
||||
graph[node1].insert(node2);
|
||||
if (0 != node1.compare(start))
|
||||
graph[node2].insert(node1);
|
||||
}
|
||||
|
||||
vector<string> beginning_path;
|
||||
beginning_path.push_back(start);
|
||||
|
||||
cout << find_all_paths(graph, beginning_path, false) << endl;
|
||||
}
|
||||
|
||||
int find_all_paths(unordered_map<string, set<string>> graph, vector<string> current_path, bool double_small_taken)
|
||||
{
|
||||
int found_paths = 0;
|
||||
set<string> connected_nodes = graph[current_path.back()];
|
||||
|
||||
for (set<string>::iterator it = connected_nodes.begin(); it != connected_nodes.end(); ++it)
|
||||
{
|
||||
string current_node = *it;
|
||||
|
||||
if (current_node.compare(finish) == 0)
|
||||
{
|
||||
++found_paths;
|
||||
}
|
||||
else if (string::npos == current_node.find_first_of(lowercase) ||
|
||||
current_path.end() == std::find(current_path.begin(), current_path.end(), current_node))
|
||||
{ //Big cave or small cave not in path
|
||||
vector<string> next_path(current_path);
|
||||
next_path.push_back(current_node);
|
||||
found_paths += find_all_paths(graph, next_path, double_small_taken);
|
||||
}
|
||||
else if (!double_small_taken)
|
||||
{ //Small cave and in path, double is not taken though
|
||||
vector<string> next_path(current_path);
|
||||
next_path.push_back(current_node);
|
||||
found_paths += find_all_paths(graph, next_path, true);
|
||||
}
|
||||
}
|
||||
|
||||
return found_paths;
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
set<pair<int,int>> flip_about(set<pair<int,int>> input_points, bool x_flip, int value);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
string line;
|
||||
bool coord_input = true;
|
||||
set<pair<int,int>> coords;
|
||||
vector<pair<bool,int>> folds;
|
||||
while(getline(cin, line))
|
||||
{
|
||||
if (0 == line.size())
|
||||
{
|
||||
coord_input = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coord_input)
|
||||
{
|
||||
string::size_type n = line.find(',');
|
||||
pair<int,int> coord(stoi(line.substr(0,n)), stoi(line.substr(n+1)));
|
||||
coords.insert(coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
string::size_type n = line.find_last_of(' ');
|
||||
line = line.substr(n+1);
|
||||
pair<bool,int> fold(line[0]=='x', stoi(line.substr(2)));
|
||||
folds.push_back(fold);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
coords = flip_about(coords, folds[0].first, folds[0].second);
|
||||
|
||||
cout << coords.size() << endl;
|
||||
}
|
||||
|
||||
set<pair<int,int>> flip_about(set<pair<int,int>> input_points, bool x_flip, int value)
|
||||
{
|
||||
set<pair<int,int>> output_points;
|
||||
set<pair<int,int>>::iterator it = input_points.begin();
|
||||
for(; it != input_points.end(); ++it)
|
||||
{
|
||||
if (x_flip)
|
||||
{
|
||||
if (it->first > value)
|
||||
{
|
||||
pair<int,int> flipped_coord(2*value-it->first, it->second);
|
||||
output_points.insert(flipped_coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_points.insert(*it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (it->second > value)
|
||||
{
|
||||
pair<int,int> flipped_coord(it->first, 2*value-it->second);
|
||||
output_points.insert(flipped_coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_points.insert(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output_points;
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
using namespace std;
|
||||
|
||||
set<pair<int,int>> flip_about(set<pair<int,int>> input_points, bool x_flip, int value);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
string line;
|
||||
bool coord_input = true;
|
||||
set<pair<int,int>> coords;
|
||||
vector<pair<bool,int>> folds;
|
||||
while(getline(cin, line))
|
||||
{
|
||||
if (0 == line.size())
|
||||
{
|
||||
coord_input = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coord_input)
|
||||
{
|
||||
string::size_type n = line.find(',');
|
||||
pair<int,int> coord(stoi(line.substr(0,n)), stoi(line.substr(n+1)));
|
||||
coords.insert(coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
string::size_type n = line.find_last_of(' ');
|
||||
line = line.substr(n+1);
|
||||
pair<bool,int> fold(line[0]=='x', stoi(line.substr(2)));
|
||||
folds.push_back(fold);
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < folds.size(); i++)
|
||||
{
|
||||
coords = flip_about(coords, folds[i].first, folds[i].second);
|
||||
}
|
||||
|
||||
int xmax = 0, ymax = 0;
|
||||
for (set<pair<int,int>>::iterator it = coords.begin(); it != coords.end(); ++it)
|
||||
{
|
||||
if (it->first > xmax)
|
||||
{
|
||||
xmax = it->first;
|
||||
}
|
||||
if (it->second > ymax)
|
||||
{
|
||||
ymax = it->second;
|
||||
}
|
||||
}
|
||||
++xmax;
|
||||
++ymax;
|
||||
|
||||
bool** marked = new bool*[xmax];
|
||||
for(int x = 0; x < xmax; x++)
|
||||
{
|
||||
marked[x] = new bool[ymax];
|
||||
for(int y = 0; y < ymax; y++)
|
||||
{
|
||||
marked[x][y] = false;
|
||||
}
|
||||
}
|
||||
|
||||
for (set<pair<int,int>>::iterator it = coords.begin(); it != coords.end(); ++it)
|
||||
{
|
||||
marked[it->first][it->second] = true;
|
||||
}
|
||||
|
||||
for (int y = 0; y < ymax; y++)
|
||||
{
|
||||
for (int x = 0; x < xmax; x++)
|
||||
{
|
||||
cout << (marked[x][y]?"#":" ");
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
for(int x = 0; x < xmax; x++)
|
||||
{
|
||||
delete[] marked[x];
|
||||
}
|
||||
delete[] marked;
|
||||
}
|
||||
|
||||
set<pair<int,int>> flip_about(set<pair<int,int>> input_points, bool x_flip, int value)
|
||||
{
|
||||
set<pair<int,int>> output_points;
|
||||
set<pair<int,int>>::iterator it = input_points.begin();
|
||||
for(; it != input_points.end(); ++it)
|
||||
{
|
||||
if (x_flip)
|
||||
{
|
||||
if (it->first > value)
|
||||
{
|
||||
pair<int,int> flipped_coord(2*value-it->first, it->second);
|
||||
output_points.insert(flipped_coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_points.insert(*it);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (it->second > value)
|
||||
{
|
||||
pair<int,int> flipped_coord(it->first, 2*value-it->second);
|
||||
output_points.insert(flipped_coord);
|
||||
}
|
||||
else
|
||||
{
|
||||
output_points.insert(*it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output_points;
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
#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;
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
#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, 40);
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue