// FR_02_08 - Walidacja adresu e-mail
#include <iostream>
#include <string>
#include <set>
#include <vector>
using namespace std;
size_t split(const string& strInput, const string& strDelim, vector<string>& vOutput)
{
size_t pos_start = 0, pos_end, delim_len = strDelim.length();
while ((pos_end = strInput.find(strDelim, pos_start)) != string::npos)
{
vOutput.push_back(strInput.substr(pos_start, pos_end - pos_start));
pos_start = pos_end + delim_len;
}
vOutput.push_back(strInput.substr(pos_start));
return vOutput.size();
}
set<char> sAllowed;
set<char> sAllowedLast;
void PrepareAllowed()
{
string strAllowed = "1234567890qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM._";
for (auto c : strAllowed)
sAllowed.insert(c);
string strAllowedLast = "qwertyuioplkjhgfdsazxcvbnmQWERTYUIOPLKJHGFDSAZXCVBNM";
for (auto c : strAllowedLast)
sAllowedLast.insert(c);
}
bool ValidatePreMalpa(const string& strInput)
{
//pierwszy ciąg znaków musi się składać z n znaków, gdzie n zawiera się w przedziale [1..20]
if (strInput.length() < 1 || strInput.length() > 20)
{
return false;
}
for (char c : strInput)
{
if (sAllowed.find(c) == sAllowed.end())
{
//niedozwolony znak
return false;
}
}
vector<string> vParts;
split(strInput, ".", vParts);
for (const string& s : vParts)
{
if (s.length() == 0)
{
//dwie kropki obok siebie lub kropka na początku lub na koncu
return false;
}
}
// cos jeszcze ?
return true;
}
bool ValidatePostMalpa(const string& strInput)
{
for (char c : strInput)
{
if (sAllowed.find(c) == sAllowed.end())
{
//niedozwolony znak
return false;
}
}
vector<string> vParts;
split(strInput, ".", vParts);
if (vParts.size() == 1) //brak kropki po @, czyli brak "trzeciego ciągu znaków" (???)
{
const string& strLast = vParts[0];
if (strLast.length() < 1 || strLast.length() > 20)
{
// drugi ciąg znaków musi się składać z n znaków, gdzie n zawiera się w przedziale [1..20]
return false;
}
}
else
{
for (const string& s : vParts)
{
if (s.length() == 0)
{
//dwie kropki obok siebie lub kropka na początku lub na koncu
return false;
}
}
const string& strLast = vParts[vParts.size() - 1];
if (strLast.length() < 2 || strLast.length() > 3)
{
//[trzeci ciąg znaków składający się z 2 lub 3 liter]
return false;
}
for (char c : strLast)
{
if (sAllowedLast.find(c) == sAllowedLast.end())
{
//trzeci ciąg znaków składający się z 2 lub 3 liter -> dozwolone tylko litery
return false;
}
}
// vParts.size() > 1
int nPostMalpaLen = strInput.length();
int nLastPartLen = strLast.length();
int nPreLastLen = nPostMalpaLen - nLastPartLen - 1;
if (nPreLastLen < 1 || nPreLastLen > 20)
{
// drugi ciąg znaków musi się składać z n znaków, gdzie n zawiera się w przedziale [1..20]
return false;
}
}
// cos jeszcze ???
return true;
}
bool ValidateAddress(const string& strInput)
{
vector<string> vParts;
split(strInput, "@", vParts);
if (vParts.size() != 2)
{
// brak małpy lub za duzo małp
return false;
}
string strPreMalpa = vParts[0];
string strPostMalpa = vParts[1];
if (strPreMalpa.length() == 0)
{
//małpa na początku
return false;
}
if (strPostMalpa.length() == 0)
{
//małpa na końcu
return false;
}
if (ValidatePreMalpa(strPreMalpa) == false)
return false;
if (ValidatePostMalpa(strPostMalpa) == false)
return false;
return true;
}
int main(int argc, char * argv[])
{
PrepareAllowed();
int nCount;
cin >> nCount;
string strLine;
getline(cin, strLine);
while (nCount--)
{
getline(cin, strLine);
if (ValidateAddress(strLine) == true)
cout << "Tak\n";
else
cout << "Nie\n";
}
return 0;
}