#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int password_length;
int num_chars;
vector<string> possible_combos;
char* chars;
void FindAll(string current,vector<int> char_ids_used)
{
if(current.length() == password_length)
{
possible_combos.push_back(current);
return;
}
for(int i = 0; i < num_chars;i++)
{
bool used = false;
for(int j = 0;j < char_ids_used.size();j++)
{
if(i == char_ids_used[j])
used = true;
}
if(!used)
{
vector<int> my_used = char_ids_used;
my_used.push_back(i);
FindAll(current + chars[i],my_used);
}
}
}
bool IsVowel(char c)
{
switch(c)
{
case 97:
case 101:
case 105:
case 111:
case 117:
return true;
}
return false;
}
bool HasVowel(string str)
{
int length = str.length();
for(int i = 0;i < length;i++)
{
if(IsVowel(str[i]))
return true;
}
return false;
}
bool HasTwoConsonants(string str)
{
int numConsonants = 0;
int length = str.length();
for(int i = 0;i < length;i++)
{
if(!IsVowel(str[i]))
numConsonants++;
}
if(numConsonants >= 2)
return true;
return false;
}
bool InAlphaOrder(string str)
{
for(int i = 1;i < str.length();i++)
{
char prev = str[i-1];
char current = str[i];
if(int(prev) > int(current))
return false;
}
return true;
}
bool InAlphaOrder(string first,string second)
{
int length = first.length();
for(int i = 0;i < length;i++)
{
if(int(first[i]) < int(second[i]))
return true;
else if(int(first[i]) > int(second[i]))
return false;
}
return true;//strings are the same
}
int main()
{
ofstream debug("passwd.debug");
debug << "Program start\n";
cout << "Program start\n";
debug << "Reading data from passwd.in\n";
cout << "Reading data from passwd.in\n";
ifstream fin("passwd.in");
fin >> password_length >> num_chars;
chars = new char[num_chars];
for(int i = 0;i < num_chars;i++)
fin >> chars[i];
fin.close();
debug << "Done reading\n";
cout << "Done reading\n";
debug << "Finding possible combos\n";
cout << "Finding possible combos\n";
for(int i = 0;i < num_chars;i++)
{
vector<int> used_chars;
used_chars.push_back(i);
string current;
current = chars[i];
FindAll(current,used_chars);
}
debug << "Done finding\n";
cout << "Done finding\n";
debug << "Validating results\n";
cout << "Validating results\n";
int num_combos = possible_combos.size();
vector<string> valid_combos;
for(int i = 0;i < num_combos;i++)//added i < 25001
{
if(!InAlphaOrder(possible_combos[i]))
continue;
if(!HasVowel(possible_combos[i]))
continue;
if(!HasTwoConsonants(possible_combos[i]))
continue;
valid_combos.push_back(possible_combos[i]);
}
debug << "Done validating\n";
cout << "Done validating\n";
possible_combos.clear();//all valid results have been copied to the valid_combos vector
debug << "Alphabetizing results\n";
cout << "Alphabetizing results\n";
for(int i = 1;i < valid_combos.size() && i <= 25000;i++)
{
if(!InAlphaOrder(valid_combos[i-1],valid_combos[i]))
{
string temp = valid_combos[i];
valid_combos[i] = valid_combos[i-1];
valid_combos[i-1] = temp;
for(int j = i-1;j > 0;j--)
{
valid_combos[j-1];
valid_combos[j];
if(InAlphaOrder(valid_combos[j-1],valid_combos[j]))
break;
else
{
temp = valid_combos[j];
valid_combos[j] = valid_combos[j-1];
valid_combos[j-1] = temp;
}
}
}
}
debug << "Done alphabetizing\n";
cout << "Done alphabetizing\n";
debug << "Outputting results\n";
cout << "Outputting results\n";
ofstream fout("passwd.out");
int size = valid_combos.size();
if(size > 25000)
size = 25000;
for(int i = 0;i < size;i++)
{
fout << valid_combos[i] << "\n";
}
debug << "Done outputting\n";
cout << "Done outputting\n";
debug << "Program end\n";
cout << "Program end\n";
fout.close();
return 0;
}