Created
November 4, 2019 04:02
-
-
Save regehr/24560ea4352e11bf6c74a0bc70b8f0e1 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <random> | |
#include <functional> | |
#include <map> | |
namespace { | |
bool enumerate; | |
std::random_device rd; | |
std::mt19937 mt(rd()); | |
typedef std::vector<std::function<std::string()>> FuncVec; | |
std::vector<int> choices, maxChoices; | |
unsigned depth; | |
const bool advance() { | |
do { | |
depth--; | |
if (choices.at(depth) < (maxChoices.at(depth) - 1)) { | |
choices.at(depth)++; | |
return true; | |
} | |
choices.pop_back(); | |
maxChoices.pop_back(); | |
} while (depth > 0); | |
return false; | |
} | |
const std::string choose(const FuncVec &v) { | |
if (enumerate) { | |
++depth; | |
if (depth > choices.size()) { | |
choices.push_back(0); | |
maxChoices.push_back(v.size()); | |
} | |
return v.at(choices.at(depth - 1))(); | |
} else { | |
std::uniform_int_distribution<> chooseN(0, v.size() - 1); | |
return v.at(chooseN(mt))(); | |
} | |
} | |
const std::string EF() { | |
return choose(FuncVec { | |
[]() { return "E"; }, | |
[]() { return "F"; } | |
}); | |
} | |
const std::string D() { | |
return choose(FuncVec { | |
[]() { return "D"; }, | |
[]() { return EF(); } | |
}); | |
} | |
const std::string C() { | |
return choose(FuncVec { | |
[]() { return "C"; }, | |
[]() { return D(); } | |
}); | |
} | |
const std::string B() { | |
return choose(FuncVec { | |
[]() { return "B"; }, | |
[]() { return C(); } | |
}); | |
} | |
const std::string A() { | |
return choose(FuncVec { | |
[]() { return "A"; }, | |
[]() { return B(); } | |
}); | |
} | |
[[ noreturn ]] void usage() { | |
std::cout << "silly-fuzz enumerate|random\n"; | |
exit(-1); | |
} | |
} // namespace | |
int main(int argc, char *argv[]) { | |
if (argc != 2) | |
usage(); | |
if (((std::string)argv[1]).compare("enumerate") == 0) | |
enumerate = true; | |
else if (((std::string)argv[1]).compare("random") == 0) | |
enumerate = false; | |
else | |
usage(); | |
if (enumerate) { | |
do { | |
depth = 0; | |
std::cout << A() << "\n"; | |
} while (advance()); | |
} else { | |
std::map<std::string, int> m; | |
const int N = 10000000; | |
for (int i = 0; i < N; i++) { | |
auto s = A(); | |
auto it = m.find(s); | |
if (it == m.end()) | |
m.insert({s, 1}); | |
else | |
++it->second; | |
} | |
for (auto it : m) | |
std::cout << it.first << " " << ((double)100 * it.second / N) << "\n"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment