#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <algorithm>
#include <cctype>
#include <unordered_map>
#include <unordered_set>
using namespace std;

bool isLeap(long long y) {
    return (y % 4 == 0 && y % 100 != 0) || (y % 400 == 0);
}

bool containsLeapYear(const string& s) {
    string num;
    for (char c : s) {
        if (isdigit(c)) num += c;
        else {
            for (int i = 0; i < (int)num.size(); i++) {
                for (int j = i + 1; j <= (int)num.size(); j++) {
                    long long y = stoll(num.substr(i, j - i));
                    if (isLeap(y)) return true;
                }
            }
            num.clear();
        }
    }
    // last run
    for (int i = 0; i < (int)num.size(); i++) {
        for (int j = i + 1; j <= (int)num.size(); j++) {
            long long y = stoll(num.substr(i, j - i));
            if (isLeap(y)) return true;
        }
    }
    return false;
}


int romanValue(const string &s) {
    unordered_map<char,int> r{{'I',1},{'V',5},{'X',10},{'L',50},{'C',100},{'D',500},{'M',1000}};
    int val = 0, prev = 0;
    for(int i = s.size()-1;i>=0;i--) {
        if(r[s[i]] < prev) val -= r[s[i]];
        else val += r[s[i]];
        prev = r[s[i]];
    }
    return val;
}

bool containsRoman(const string &pw) {
    for(char c : pw) if(c=='I'||c=='V'||c=='X'||c=='L'||c=='C'||c=='D'||c=='M') return true;
    return false;
}

int main(int argc, char *argv[]) {
    if(argc<4) {
        cout << "4 arguments needed!" << endl;
        return 0;
    }

    ifstream file(argv[3]);
    string pw;
    getline(file, pw);
    ifstream testNr(argv[1]);
    int nr;
    testNr >> nr;
    bool res;
    string specials = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";

    unordered_set<string> months{"january","february","march","april","may","june",
                                 "july","august","september","october","november","december"};
    unordered_set<string> sponsors{"mitko","bobi","kiki"};
    unordered_set<string> twoLetterElements{"he","li","be","ne","na","mg","al","si","cl","ar",
                                            "ca","sc","ti","cr","mn","fe","co","ni","cu","zn","ga","ge",
                                            "as","se","br","kr","rb","sr","y","zr","nb","mo","tc",
                                            "ru","rh","pd","ag","cd","in","sn","sb","te","xe",
                                            "cs","ba","la","ce","pr","nd","pm","sm","eu","gd",
                                            "tb","dy","ho","er","tm","yb","lu","hf","ta","re",
                                            "os","ir","pt","au","hg","tl","pb","bi","po","at","rn",
                                            "fr","ra","ac","th","pa","u","np","pu","am","cm","bk","cf",
                                            "es","fm","md","no","lr","rf","db","sg","bh","hs","mt","ds","rg","cn","fl","lv"};

    string captcha = "dbfen";
    string wordle_word = "throb";
    string country_name = "sweden";
    string best_chess_move = "Nf7+";
    string w="";

    // 1. >=5 символа
    if(nr==1) {
        res = (pw.size() >= 5);
        w="Паролата трябва да е поне 5 символа.";
    }
    // 2. съдържа число
    if(nr==2) {
        res = any_of(pw.begin(),pw.end(),[](char c){return isdigit(c);});
        w="Паролата трябва да съдържа число.";
    }
    // 3. главна буква
    if(nr==3) {
        res = any_of(pw.begin(),pw.end(),[](char c){return isupper(c);});
        w="Паролата трябва да съдържа главна буква.";
    }
    // 4. специален символ
    if(nr==4) {
        res = any_of(pw.begin(),pw.end(),[&](char c){return specials.find(c)!=string::npos;});
        w="Паролата трябва да съдържа специален символ (@, !, %, $, &, *, т.н.).";
    }
    // 5. сума на цифрите = 25
    if(nr==5) {
        int sumDigits = 0;
        for(char c : pw) if(isdigit(c)) sumDigits += c-'0';
        res = sumDigits==25;
        w="Цифрите в паролата трябва да имат сума 25.";
    }

    // lowercase version
    string pwLower = pw;
    transform(pwLower.begin(),pwLower.end(),pwLower.begin(),::tolower);

    // 6. месец
    if(nr==6) {
        bool hasMonth=false;
        for(auto &m:months) if(pwLower.find(m)!=string::npos) hasMonth=true;
        res = hasMonth;
        w="Паролата трябва да съдържа месец от годината на английски с малки латински букви.";
    }
    
    // 7. римска цифра
    if(nr==7) {
        res = containsRoman(pw);
        w="Паролата трябва да съдържа число с римски цифри с главни букви.";
    }

    // 8. спонсор
    if(nr==8) {
        bool hasSponsor=false;
        for(auto &s:sponsors) if(pwLower.find(s)!=string::npos) hasSponsor=true;
        res = hasSponsor;
        w="Паролата трябва да съдържа името на един от нашите спонсори: mitko, bobi, kiki.";
    }
    
    // 9. произведение на римските цифри = 35
    if(nr==9) {
        int prod=1;
        bool foundRoman=false;
        string tmp;
        for(char c:pw) {
            if(c=='I'||c=='V'||c=='X'||c=='L'||c=='C'||c=='D'||c=='M') tmp+=c;
            else if(!tmp.empty()) {
                foundRoman=true;
                prod *= romanValue(tmp);
                tmp.clear();
            }
        }
        if(!tmp.empty()) {foundRoman=true; prod*=romanValue(tmp);}
        if(!foundRoman) prod=0;
        res = prod==35;
        w="Произведението на римските цифри в паролата трябва да е 35.";
    }
    
    // 10. CAPTCHA
    if(nr==10) {
        res = (pw.find(captcha)!=string::npos);
        w="Паролата трябва да съдържа CAPTCHA-та в фигура 1.";
    }
    // 11. Wordle
    if(nr==11) {
        res = (pw.find(wordle_word)!=string::npos);
        w="Паролата трябва да съдържа Wordle думата за 12 септември 2025.";
    }

    // 12. двубуквен елемент
    if(nr==12) {
        bool hasElement=false;
        for(auto &e:twoLetterElements) if(pwLower.find(e)!=string::npos) hasElement=true;
        res = hasElement;
        w="Паролата трябва да съдържа елемент от периодичната таблица, съставен от две букви.";
    }
    
    // 13. държава
    if(nr==13) {
        res = (pwLower.find(country_name)!=string::npos);
        w="Паролата трябва да съдържа името на държавата в снимката в фигура 2, написано с малки латински букви.";
    }

    // 14. високосна година
    if(nr==14) {
        res = containsLeapYear(pwLower);
        w="Паролата трябва да съдържа високосна година.";
    }
    
    // 15. шах ход
    if(nr==15) {
        res = (pw.find(best_chess_move)!=string::npos);
        w="Паролата трябва да съдържа най-добрия ход за белите фигури в позицията в фигура 3.";
    }
    
    cout << res << endl;
    if(res==0) {
        cerr << w << endl;
    }
}
