summaryrefslogtreecommitdiff
path: root/2015/day19.cpp
blob: 7afa3e77547b57476673f55b0fe4b1ad4d964462 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <fstream>
#include <string>
#include <unordered_map>
#include <vector>
#include <utility>

using namespace std;

bool search(const vector<pair<string,string>> &repls,const string &target,string from,int depth){
	if(from==target)return true;
	if(depth<=0)return false;
	int i,j,r,l;
	const int fromlen=from.size(),nrepls=repls.size();
	for(i=0;i<fromlen;i++){
		for(r=0;r<nrepls;r++){
			l=repls[r].first.size();
			if(fromlen-i<l)continue;
			for(j=0;j<l;j++)if(from[i+j]!=repls[r].first[j])break;
			if(j<l)continue;
			if(search(repls,
			          target,
			          from.substr(0,i)+repls[r].second+from.substr(i+repls[r].first.size()),
			          depth-1)){
				cerr<<repls[r].first<<" -> "<<repls[r].second<<" (at "<<i<<" in "<<from<<')'<<endl;
				return true;
			}
		}
	}
	return false;
}

int cheat(const vector<pair<string,string>> &repls,const string &target,string from){
	int i,r,j,l;
	int depth;
	const int fromlen=from.size(),nrepls=repls.size();
	for(depth=0;from!=target;depth++){
		for(i=0;i<fromlen;i++){
			for(r=0;r<nrepls;r++){
				l=repls[r].first.size();
				if(fromlen-i<l)continue;
				for(j=0;j<l;j++)if(from[i+j]!=repls[r].first[j])break;
				if(j<l)continue;
				from=from.substr(0,i)+repls[r].second+from.substr(i+repls[r].first.size());
				i=fromlen+41; break;
			}
		}
		if(i!=fromlen+42)return -1;
		cout<<from<<endl;
	}
	return depth;
}

int main(void){
	ifstream in("day19.txt");
	string line,target;
	int a,b;
	vector<pair<string,string>> repls;
	while(true){
		getline(in,line);
		if(line.size()==0){
			getline(in,target);
			break;
		}
		if(!in)break;
		a=line.find(' ');
		b=line.find(' ',a+1);
		// repls.emplace_back(line.substr(0,a),line.substr(b+1));
		repls.emplace_back(line.substr(b+1),line.substr(0,a)); //reversed
	}

	// repls={{"H","HO"},{"H","OH"},{"O","HH"},{"e","O"},{"e","H"}};
	// repls={{"HO","H"},{"OH","H"},{"HH","O"},{"O","e"},{"H","e"}}; //reversed
	// target="HOHOHO";

	//for(const pair<string,string> &p : repls)cout<<"repl: "<<p.first<<" -> "<<p.second<<endl;
	//cout<<"target: "<<target<<endl;

	cout<<cheat(repls,"e",target)<<endl;

	int depth;
	for(depth=1;;depth++){
		cerr<<"Starting depth "<<depth<<"..."<<endl;
		// const bool res=search(repls,target,"e",depth);
		const bool res=search(repls,"e",target,depth); //reversed
		if(res)break;
	}
	cout<<depth<<endl;
}