Language: C++

#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <boost/rational.hpp>
using namespace std;
typedef unordered_map<string,long long> molecule;

molecule dfs(const vector<string> &s,int L,int R){
	molecule r;
	int i=L;
	long long n=1;
	for(;i<R;){
		if('0'<=s[i][0]&&s[i][0]<='9'){
			n=strtol(s[i].c_str(),NULL,10);
			i++;
		}else if(s[i]=="("){
			int cnt=1,j=i+1;
			for(;cnt;){
				if(s[j]=="(")
					cnt++;
				else if(s[j]==")")
					cnt--;
				j++;
			}
			auto r0=dfs(s,i+1,j-1);
			for(auto &e:r0){
				r[e.first]+=n*e.second;
			}
			n=1;
			i=j;
		}else{
			r[s[i]]+=n;
			n=1;
			i++;
		}
	}
	return r;
}
vector<string> tokenize_rev(const string &s){
	vector<string> v;
	for(int i=0;i<s.size();){
		if(s[i]=='('){
			v.push_back(")"),i++;
		}else if(s[i]==')'){
			v.push_back("("),i++;
		}else if('0'<=s[i]&&s[i]<='9'){
			int j=i+1;
			for(;'0'<=s[j]&&s[j]<='9';j++);
			v.push_back(s.substr(i,j-i));
			i=j;
		}else if('A'<=s[i]&&s[i]<='Z'){
			int j=i+1;
			for(;'a'<=s[j]&&s[j]<='z';j++);
			v.push_back(s.substr(i,j-i));
			i=j;
		}
	}
	reverse(v.begin(),v.end());
	return v;
}

bool gauss(vector<vector<boost::rational<long long> > > &a){
	if(a.empty())return false;
	int n=a.size(),i=0;
	for(;i<n;i++){
		if(!a[i][i]){
			int j=i+1;
			for(;j<n;j++){
				if(a[j][i]){
					for(int k=i;k<a[0].size();k++)a[i][k]+=a[j][k];
					break;
				}
			}
			if(j==n)break;
		}
		for(int j=0;j<n;j++)if(i!=j){
			auto r=a[j][i]/a[i][i];
			for(int k=i;k<a[0].size();k++)a[j][k]=a[j][k]-a[i][k]*r;
		}
	}
	for(i--;i>=0;i--){
		auto x=a[i][i];
		for(int j=0;j<a[i].size();j++)a[i][j]/=x;
	}
	return true;
}

long long gcd(long long x,long long y){return y?gcd(y,x%y):x;}
long long lcm(long long x,long long y){return y/gcd(x,y)*x;}
int main(){
	string line;
	for(;getline(cin,line),line!=".";){
		unordered_set<string> _elements;
		vector<molecule> formula;
		int prev=0,cur=0,factor=1;
		for(;cur<line.size();cur++){
			if(line[cur]=='+'||line[cur]=='-'||line[cur]=='.'){
				vector<string> token=tokenize_rev(line.substr(prev,cur-prev));
				auto r=dfs(token,0,token.size());
				for(auto &&e:r){
					_elements.insert(e.first);
					e.second*=factor;
				}
				formula.push_back(r);
				if(line[cur]=='-')factor=-1,cur++;
				prev=cur+1;
			}
		}
		vector<string> elements=vector<string>(_elements.begin(),_elements.end());
		//should be formula.size(). otherwise some elements have the same ratio.
		vector<vector<boost::rational<long long>> >a(elements.size()+1);
		for(int i=0;i<a.size();i++){
			a[i].resize(formula.size()+1);
			if(i<a.size()-1){
				for(int j=0;j<formula.size();j++){
					if(formula[j][elements[i]]){
						a[i][j]=formula[j][elements[i]]>0?1:-1;
						a[i][j]=boost::rational<long long>(a[i][j]*abs(formula[j][elements[i]]));
					}
				}
			}else{
				for(int j=0;j<formula.size();j++)a[i][j]=1;
				a[i][formula.size()]=1;
			}
		}
		gauss(a);
		long long L=1;
		for(int i=0;i<formula.size();i++)L=lcm(L,a[i][formula.size()].denominator());
		for(int i=0;i<formula.size();i++)printf(i<formula.size()-1?"%lld ":"%lld\n",L/a[i][formula.size()].denominator()*a[i][formula.size()].numerator());
	}
}

Compiler output:
a.cc:9:10: fatal error: boost/rational.hpp: No such file or directory
    9 | #include <boost/rational.hpp>
      |          ^~~~~~~~~~~~~~~~~~~~
compilation terminated.