#include <iostream>
#include <string>
#include <vector>
#include <memory>
#include <map>
#include <tuple>
struct Item{
virtual char GetToken()=0;
};
struct Num :public Item {
int N;
Num(int N_){
N = N_;
}
char GetToken(){
return 'N';
}
};
struct Token :public Item {
char C;
Token(char C_){
C = C_;
}
char GetToken(){
return C;
}
};
struct bunsuu :public Item {
public:
int C,M;
bunsuu(int C_, int M_){
C = C_;
M = M_;
}
char GetToken(){
return ':';
}
};
typedef std::shared_ptr<Item> IType;
typedef std::vector<IType> MType;
typedef std::tuple<MType, MType> PType;
int ToNumber(wchar_t C){
std::map<wchar_t, int> m{ { L'0', 0 }, { L'1', 1 }, { L'2', 2 }, { L'3', 3 }, { L'4', 4 }, { L'5', 5 }, { L'6', 6 }, { L'7', 7 }, { L'8', 8 }, { L'9', 9 }, };
return m[C];
}
char ToToken(wchar_t C){
std::map<wchar_t, char> m{ { L'/', ':' }, { L'÷', '/' }, { L'+', '+' }, { L'-', '-' }, { L'×', '*' }, { L'*', '*' }};//分数記号はなんかいい案無いだろうか。
return m[C];
}
bool IsNumber(wchar_t C){
std::map<wchar_t, bool> m{ { L'0', true }, { L'1', true }, { L'2', true }, { L'3', true }, { L'4', true }, { L'5', true }, { L'6', true }, { L'7', true }, { L'8', true }, { L'9', true }, };
return m[C];
}
bool IsToken(wchar_t C){
std::map<wchar_t, bool> m{ { L'/', true }, { L'÷', true }, { L'+', true }, { L'-', true }, { L'×', true }, { L'*', true }};
return m[C];
}
MType MakeSiki(std::wstring& s){
MType R;
std::shared_ptr<Item> I;
for (std::size_t i = 0; i < s.length(); i++){
switch (s[i])
{
case L'1':
case L'2':
case L'3':
case L'4':
case L'5':
case L'6':
case L'7':
case L'8':
case L'9':
R.push_back(std::make_shared<Num>(ToNumber(s[i])));
break;
case L'+':
case L'-':
case L'*':
case L'×':
case L'÷':
R.push_back(std::make_shared<Token>(ToToken(s[i])));
break;
case L'/':
I = R.back();
R.pop_back();
R.push_back(std::make_shared<bunsuu>(static_cast<Num*>(&(*I))->N, ToNumber(s[i + 1])));
i++;
break;
default:
break;
}
}
return R;
}
PType SepSiki(MType& s){
MType N;
MType T;
for (auto&o : s){
switch (o->GetToken())
{
case ':':
case 'N':
N.push_back(o);
break;
case '+':
case '-':
case '*':
case '/':
T.push_back(o);
break;
default:
break;
}
}
return std::make_tuple(N, T);
}
IType CalcOne(int A, int B,char o){
switch (o)
{
case '+':
return std::make_shared<Num>(A + B);
case '-':
return std::make_shared<Num>(A - B);
case '*':
return std::make_shared<Num>(A * B);
case '/':
return std::make_shared<bunsuu>(A , B);
default:
break;
}
return std::make_shared<Num>(0);
}
IType CalcOne(bunsuu A, bunsuu B,char o){
bunsuu C(1,1);
bunsuu D(A.C*B.M, A.M*B.M);//GCDが無いとオーバーフローする。
bunsuu E(B.C*A.M, B.M*A.M);
switch (o)
{
case '+':
C.M = D.M;
C.C = D.C+E.C;
break;
case '-':
C.M = D.M;
C.C = D.C-E.C;
break;
case '*':
C.M = B.M*A.M;
C.C = B.C*A.C;
break;
case '/':
C.M = B.C*A.M;
C.C = B.M*A.C;
break;
default:
break;
}
if (C.C%C.M == 0){
return std::make_shared<Num>(C.C / C.M);
}
else{
return std::make_shared<bunsuu>(C);
}
}
IType CalcOne(bunsuu A, int B,char o){
return std::make_shared<Num>(-1);
}
IType CalcOne(int A, bunsuu B,char o){
bunsuu C(1,1);
switch (o)
{
case '/':
C.M = B.C;
C.C = B.M*A;
break;
default:
break;
}
if (C.C%C.M == 0){
return std::make_shared<Num>(C.C / C.M);
}
else{
return std::make_shared<bunsuu>(C);
}
}
IType CalcOne(IType a, IType b, IType o){
if (a->GetToken() == 'N'){
if (b->GetToken() == 'N'){
return CalcOne(static_cast<Num*>(&(*a))->N, static_cast<Num*>(&(*b))->N, o->GetToken());
}
else{
return CalcOne(static_cast<Num*>(&(*a))->N, *static_cast<bunsuu*>(&(*b)), o->GetToken());
}
}
else{
if (b->GetToken() == 'N'){
return CalcOne(*static_cast<bunsuu*>(&(*a)), static_cast<Num*>(&(*b))->N, o->GetToken());
}
else{
return CalcOne(*static_cast<bunsuu*>(&(*a)), *static_cast<bunsuu*>(&(*b)), o->GetToken());
}
}
/** /
return CalcOne(
a->GetToken() == 'N' ? (static_cast<Num*>(&(*a)))->N : *static_cast<bunsuu*>(&(*a)),
a->GetToken() == 'N' ? (static_cast<Num*>(&(*a)))->N : *static_cast<bunsuu*>(&(*a)),
o->GetToken()
);
*/
return std::make_shared<Num>(-1);
}
IType Calc(PType& P){
MType &N = std::get<0>(P);
MType &T = std::get<1>(P);
for (std::size_t i = 0; i < T.size(); i++){
if (T[i]->GetToken() == '*' || T[i]->GetToken() == '/'){
N[i] = CalcOne(N[i], N[i + 1], T[i]);
N.erase(N.begin() + i + 1);
T.erase(T.begin() + i);
i--;
}
}
for (std::size_t i = 0; i < T.size(); i++){
if (T[i]->GetToken() == '+' || T[i]->GetToken() == '-'){
N[i] = CalcOne(N[i], N[i + 1], T[i]);
N.erase(N.begin() + i + 1);
T.erase(T.begin() + i);
i--;
}
}
return N[0];
}
//コピペした。もう無理。
//http://w...content-available-to-author-only...l.edu/~victor/mfmm/
//http://w...content-available-to-author-only...l.edu/~victor/mfmm/compaa/gcd.c
int gcd(int a, int b)
{
int c;
while (a != 0) {
c = a; a = b%a; b = c;
}
return b;
}
bool Show(IType i){
if (i->GetToken() == 'N'){
std::cout<<static_cast<Num*>(&(*i))->N<<std::endl;
}
else{
bunsuu &b = *static_cast<bunsuu*>(&(*i));
int N = gcd(b.C, b.M);
std::cout<<b.C/N<<'/'<<b.M/N<<std::endl;
}
return true;
}
IType MakeHoge(std::wstring s){
MType Siki = MakeSiki(s);
PType P = SepSiki(Siki);
IType R = Calc(P);
return R;
}
int main(){
IType A = 0;
A = MakeHoge(L"9-3÷1/3+1");
Show(A);
A = MakeHoge(L"1/2÷3/4÷5/6×7/8");
Show(A);
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3RyaW5nPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8bWFwPgojaW5jbHVkZSA8dHVwbGU+CgpzdHJ1Y3QgSXRlbXsKCXZpcnR1YWwgY2hhciBHZXRUb2tlbigpPTA7Cn07CnN0cnVjdCBOdW0gOnB1YmxpYyBJdGVtIHsKCWludCBOOwoJTnVtKGludCBOXyl7CgkJTiA9IE5fOwoJfQoJY2hhciBHZXRUb2tlbigpewoJCXJldHVybiAnTic7Cgl9Cn07CnN0cnVjdCBUb2tlbiA6cHVibGljIEl0ZW0gewoJY2hhciBDOwoJVG9rZW4oY2hhciBDXyl7CgkJQyA9IENfOwoJfQoJY2hhciBHZXRUb2tlbigpewoJCXJldHVybiBDOwoJfQp9OwoKc3RydWN0IGJ1bnN1dSA6cHVibGljIEl0ZW0gewpwdWJsaWM6CglpbnQgQyxNOwoKCWJ1bnN1dShpbnQgQ18sIGludCBNXyl7CgkJQyA9IENfOwoJCU0gPSBNXzsKCX0KCgljaGFyIEdldFRva2VuKCl7CgkJcmV0dXJuICc6JzsKCX0KCn07CnR5cGVkZWYgc3RkOjpzaGFyZWRfcHRyPEl0ZW0+IElUeXBlOwp0eXBlZGVmIHN0ZDo6dmVjdG9yPElUeXBlPiBNVHlwZTsKdHlwZWRlZiBzdGQ6OnR1cGxlPE1UeXBlLCBNVHlwZT4gUFR5cGU7CgoKaW50IFRvTnVtYmVyKHdjaGFyX3QgQyl7CglzdGQ6Om1hcDx3Y2hhcl90LCBpbnQ+IG17IHsgTCfvvJAnLCAwIH0sIHsgTCfvvJEnLCAxIH0sIHsgTCfvvJInLCAyIH0sIHsgTCfvvJMnLCAzIH0sIHsgTCfvvJQnLCA0IH0sIHsgTCfvvJUnLCA1IH0sIHsgTCfvvJYnLCA2IH0sIHsgTCfvvJcnLCA3IH0sIHsgTCfvvJgnLCA4IH0sIHsgTCfvvJknLCA5IH0sIH07CgoJcmV0dXJuIG1bQ107Cn0KY2hhciBUb1Rva2VuKHdjaGFyX3QgQyl7CglzdGQ6Om1hcDx3Y2hhcl90LCBjaGFyPiBteyB7IEwn77yPJywgJzonIH0sIHsgTCfDtycsICcvJyB9LCB7IEwn77yLJywgJysnIH0sIHsgTCfvvI0nLCAnLScgfSwgeyBMJ8OXJywgJyonIH0sIHsgTCfvvIonLCAnKicgfX07Ly/liIbmlbDoqJjlj7fjga/jgarjgpPjgYvjgYTjgYTmoYjnhKHjgYTjgaDjgo3jgYbjgYvjgIIKCQoJcmV0dXJuIG1bQ107Cn0KYm9vbCBJc051bWJlcih3Y2hhcl90IEMpewoJc3RkOjptYXA8d2NoYXJfdCwgYm9vbD4gbXsgeyBMJ++8kCcsIHRydWUgfSwgeyBMJ++8kScsIHRydWUgfSwgeyBMJ++8kicsIHRydWUgfSwgeyBMJ++8kycsIHRydWUgfSwgeyBMJ++8lCcsIHRydWUgfSwgeyBMJ++8lScsIHRydWUgfSwgeyBMJ++8licsIHRydWUgfSwgeyBMJ++8lycsIHRydWUgfSwgeyBMJ++8mCcsIHRydWUgfSwgeyBMJ++8mScsIHRydWUgfSwgfTsKCglyZXR1cm4gbVtDXTsKfQpib29sIElzVG9rZW4od2NoYXJfdCBDKXsKCXN0ZDo6bWFwPHdjaGFyX3QsIGJvb2w+IG17IHsgTCfvvI8nLCB0cnVlIH0sIHsgTCfDtycsIHRydWUgfSwgeyBMJ++8iycsIHRydWUgfSwgeyBMJ++8jScsIHRydWUgfSwgeyBMJ8OXJywgdHJ1ZSB9LCB7IEwn77yKJywgdHJ1ZSB9fTsKCglyZXR1cm4gbVtDXTsKfQoKTVR5cGUgTWFrZVNpa2koc3RkOjp3c3RyaW5nJiBzKXsKCU1UeXBlIFI7CglzdGQ6OnNoYXJlZF9wdHI8SXRlbT4gSTsKCWZvciAoc3RkOjpzaXplX3QgaSA9IDA7IGkgPCBzLmxlbmd0aCgpOyBpKyspewoJCXN3aXRjaCAoc1tpXSkKCQl7CgkJCWNhc2UgTCfvvJEnOgoJCQljYXNlIEwn77ySJzoJCgkJCWNhc2UgTCfvvJMnOgoJCQljYXNlIEwn77yUJzoKCQkJY2FzZSBMJ++8lSc6CQoJCQljYXNlIEwn77yWJzoKCQkJY2FzZSBMJ++8lyc6CgkJCWNhc2UgTCfvvJgnOgkKCQkJY2FzZSBMJ++8mSc6CgkJCQlSLnB1c2hfYmFjayhzdGQ6Om1ha2Vfc2hhcmVkPE51bT4oVG9OdW1iZXIoc1tpXSkpKTsKCQkJCWJyZWFrOwoJCQljYXNlIEwn77yLJzoKCQkJY2FzZSBMJ++8jSc6CQoJCQljYXNlIEwn77yKJzoKCQkJY2FzZSBMJ8OXJzoKCQkJY2FzZSBMJ8O3JzoKCQkJCVIucHVzaF9iYWNrKHN0ZDo6bWFrZV9zaGFyZWQ8VG9rZW4+KFRvVG9rZW4oc1tpXSkpKTsKCQkJCWJyZWFrOwoJCQljYXNlIEwn77yPJzoKCQkJCUkgPSBSLmJhY2soKTsKCQkJCVIucG9wX2JhY2soKTsKCQkJCVIucHVzaF9iYWNrKHN0ZDo6bWFrZV9zaGFyZWQ8YnVuc3V1PihzdGF0aWNfY2FzdDxOdW0qPigmKCpJKSktPk4sIFRvTnVtYmVyKHNbaSArIDFdKSkpOwoJCQkJaSsrOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQlicmVhazsKCQl9Cgl9CglyZXR1cm4gUjsKfQoKUFR5cGUgU2VwU2lraShNVHlwZSYgcyl7CglNVHlwZSBOOwoJTVR5cGUgVDsKCWZvciAoYXV0byZvIDogcyl7CgkJc3dpdGNoIChvLT5HZXRUb2tlbigpKQoJCXsKCQkJY2FzZSAnOic6CgkJCWNhc2UgJ04nOgoJCQkJTi5wdXNoX2JhY2sobyk7CgkJCQlicmVhazsKCQkJY2FzZSAnKyc6CgkJCWNhc2UgJy0nOgoJCQljYXNlICcqJzoKCQkJY2FzZSAnLyc6CgkJCQlULnB1c2hfYmFjayhvKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJYnJlYWs7CgkJfQoJfQoKCXJldHVybiBzdGQ6Om1ha2VfdHVwbGUoTiwgVCk7Cn0KCklUeXBlIENhbGNPbmUoaW50IEEsIGludCBCLGNoYXIgbyl7Cglzd2l0Y2ggKG8pCgl7CgkJY2FzZSAnKyc6CgkJCXJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPE51bT4oQSArIEIpOwoJCWNhc2UgJy0nOgoJCQlyZXR1cm4gc3RkOjptYWtlX3NoYXJlZDxOdW0+KEEgLSBCKTsKCQljYXNlICcqJzoKCQkJcmV0dXJuIHN0ZDo6bWFrZV9zaGFyZWQ8TnVtPihBICogQik7CgkJY2FzZSAnLyc6CgkJCXJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPGJ1bnN1dT4oQSAsIEIpOwoJCQoJCWRlZmF1bHQ6CgkJCWJyZWFrOwoJfQoJcmV0dXJuIHN0ZDo6bWFrZV9zaGFyZWQ8TnVtPigwKTsKfQpJVHlwZSBDYWxjT25lKGJ1bnN1dSBBLCBidW5zdXUgQixjaGFyIG8pewoJYnVuc3V1IEMoMSwxKTsKCWJ1bnN1dSBEKEEuQypCLk0sIEEuTSpCLk0pOy8vR0NE44GM54Sh44GE44Go44Kq44O844OQ44O844OV44Ot44O844GZ44KL44CCCglidW5zdXUgRShCLkMqQS5NLCBCLk0qQS5NKTsKCXN3aXRjaCAobykKCXsKCQljYXNlICcrJzoKCQkJQy5NID0gRC5NOwoJCQlDLkMgPSBELkMrRS5DOwoJCQlicmVhazsKCQljYXNlICctJzoKCQkJQy5NID0gRC5NOwoJCQlDLkMgPSBELkMtRS5DOwoJCQlicmVhazsKCgkJY2FzZSAnKic6CgkJCUMuTSA9IEIuTSpBLk07CgkJCUMuQyA9IEIuQypBLkM7CgkJCWJyZWFrOwoJCWNhc2UgJy8nOgoJCQlDLk0gPSBCLkMqQS5NOwoJCQlDLkMgPSBCLk0qQS5DOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJYnJlYWs7Cgl9CgoJaWYgKEMuQyVDLk0gPT0gMCl7CgkJcmV0dXJuIHN0ZDo6bWFrZV9zaGFyZWQ8TnVtPihDLkMgLyBDLk0pOwoJfQoJZWxzZXsKCQlyZXR1cm4gc3RkOjptYWtlX3NoYXJlZDxidW5zdXU+KEMpOwoJfQkKfQpJVHlwZSBDYWxjT25lKGJ1bnN1dSBBLCBpbnQgQixjaGFyIG8pewoJCXJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPE51bT4oLTEpOwp9CklUeXBlIENhbGNPbmUoaW50IEEsIGJ1bnN1dSBCLGNoYXIgbyl7CglidW5zdXUgQygxLDEpOwoJc3dpdGNoIChvKQoJewoJCWNhc2UgJy8nOgoJCQlDLk0gPSBCLkM7CgkJCUMuQyA9IEIuTSpBOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlicmVhazsKCX0KCglpZiAoQy5DJUMuTSA9PSAwKXsKCQlyZXR1cm4gc3RkOjptYWtlX3NoYXJlZDxOdW0+KEMuQyAvIEMuTSk7Cgl9CgllbHNlewoJCXJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPGJ1bnN1dT4oQyk7Cgl9Cgp9CgpJVHlwZSBDYWxjT25lKElUeXBlIGEsIElUeXBlIGIsIElUeXBlIG8pewoKCWlmIChhLT5HZXRUb2tlbigpID09ICdOJyl7CgkJaWYgKGItPkdldFRva2VuKCkgPT0gJ04nKXsKCQkJcmV0dXJuIENhbGNPbmUoc3RhdGljX2Nhc3Q8TnVtKj4oJigqYSkpLT5OLCBzdGF0aWNfY2FzdDxOdW0qPigmKCpiKSktPk4sIG8tPkdldFRva2VuKCkpOwoJCX0KCQllbHNlewoJCQlyZXR1cm4gQ2FsY09uZShzdGF0aWNfY2FzdDxOdW0qPigmKCphKSktPk4sICpzdGF0aWNfY2FzdDxidW5zdXUqPigmKCpiKSksIG8tPkdldFRva2VuKCkpOwoJCX0KCX0KCWVsc2V7CgkJaWYgKGItPkdldFRva2VuKCkgPT0gJ04nKXsKCQkJcmV0dXJuIENhbGNPbmUoKnN0YXRpY19jYXN0PGJ1bnN1dSo+KCYoKmEpKSwgc3RhdGljX2Nhc3Q8TnVtKj4oJigqYikpLT5OLCBvLT5HZXRUb2tlbigpKTsKCQl9CgkJZWxzZXsKCQkJcmV0dXJuIENhbGNPbmUoKnN0YXRpY19jYXN0PGJ1bnN1dSo+KCYoKmEpKSwgKnN0YXRpY19jYXN0PGJ1bnN1dSo+KCYoKmIpKSwgby0+R2V0VG9rZW4oKSk7CgkJfQoJfQoKCQkvKiogLwoJcmV0dXJuIENhbGNPbmUoCgkJCQlhLT5HZXRUb2tlbigpID09ICdOJyA/IChzdGF0aWNfY2FzdDxOdW0qPigmKCphKSkpLT5OIDogKnN0YXRpY19jYXN0PGJ1bnN1dSo+KCYoKmEpKSwKCQkJCWEtPkdldFRva2VuKCkgPT0gJ04nID8gKHN0YXRpY19jYXN0PE51bSo+KCYoKmEpKSktPk4gOiAqc3RhdGljX2Nhc3Q8YnVuc3V1Kj4oJigqYSkpLAoJCQkJby0+R2V0VG9rZW4oKQoJCSk7CgkJKi8KCXJldHVybiBzdGQ6Om1ha2Vfc2hhcmVkPE51bT4oLTEpOwp9CgpJVHlwZSBDYWxjKFBUeXBlJiBQKXsKCU1UeXBlICZOID0gc3RkOjpnZXQ8MD4oUCk7CglNVHlwZSAmVCA9IHN0ZDo6Z2V0PDE+KFApOwoJZm9yIChzdGQ6OnNpemVfdCBpID0gMDsgaSA8IFQuc2l6ZSgpOyBpKyspewoJCWlmIChUW2ldLT5HZXRUb2tlbigpID09ICcqJyB8fCBUW2ldLT5HZXRUb2tlbigpID09ICcvJyl7CgkJCU5baV0gPSBDYWxjT25lKE5baV0sIE5baSArIDFdLCBUW2ldKTsKCQkJTi5lcmFzZShOLmJlZ2luKCkgKyBpICsgMSk7CgkJCVQuZXJhc2UoVC5iZWdpbigpICsgaSk7CgkJCWktLTsKCQl9Cgl9Cglmb3IgKHN0ZDo6c2l6ZV90IGkgPSAwOyBpIDwgVC5zaXplKCk7IGkrKyl7CgkJaWYgKFRbaV0tPkdldFRva2VuKCkgPT0gJysnIHx8IFRbaV0tPkdldFRva2VuKCkgPT0gJy0nKXsKCQkJTltpXSA9IENhbGNPbmUoTltpXSwgTltpICsgMV0sIFRbaV0pOwoJCQlOLmVyYXNlKE4uYmVnaW4oKSArIGkgKyAxKTsKCQkJVC5lcmFzZShULmJlZ2luKCkgKyBpKTsKCQkJaS0tOwoJCX0KCX0KCXJldHVybiBOWzBdOwp9CgovL+OCs+ODlOODmuOBl+OBn+OAguOCguOBhueEoeeQhuOAggovL2h0dHA6Ly93Li4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5sLmVkdS9+dmljdG9yL21mbW0vCi8vaHR0cDovL3cuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLmwuZWR1L352aWN0b3IvbWZtbS9jb21wYWEvZ2NkLmMKaW50IGdjZChpbnQgYSwgaW50IGIpCnsKCWludCBjOwoJd2hpbGUgKGEgIT0gMCkgewoJCWMgPSBhOyBhID0gYiVhOyAgYiA9IGM7Cgl9CglyZXR1cm4gYjsKfQoKYm9vbCBTaG93KElUeXBlIGkpewoJaWYgKGktPkdldFRva2VuKCkgPT0gJ04nKXsKCQlzdGQ6OmNvdXQ8PHN0YXRpY19jYXN0PE51bSo+KCYoKmkpKS0+Tjw8c3RkOjplbmRsOwoJfQoJZWxzZXsKCQlidW5zdXUgJmIgPSAqc3RhdGljX2Nhc3Q8YnVuc3V1Kj4oJigqaSkpOwoJCWludCBOID0gZ2NkKGIuQywgYi5NKTsKCQlzdGQ6OmNvdXQ8PGIuQy9OPDwnLyc8PGIuTS9OPDxzdGQ6OmVuZGw7Cgl9CglyZXR1cm4gIHRydWU7Cn0KCklUeXBlIE1ha2VIb2dlKHN0ZDo6d3N0cmluZyBzKXsKCU1UeXBlIFNpa2kgPSBNYWtlU2lraShzKTsKCVBUeXBlIFAgPSBTZXBTaWtpKFNpa2kpOwoKCUlUeXBlIFIgPSBDYWxjKFApOwoKCXJldHVybiBSOwp9CgppbnQgbWFpbigpewoJSVR5cGUgQSA9IDA7CgoJQSA9IE1ha2VIb2dlKEwi77yZ77yN77yTw7fvvJHvvI/vvJPvvIvvvJEiKTsKCVNob3coQSk7CglBID0gTWFrZUhvZ2UoTCLvvJHvvI/vvJLDt++8k++8j++8lMO377yV77yP77yWw5fvvJfvvI/vvJgiKTsKCVNob3coQSk7CgoJcmV0dXJuIDA7Cn0=