Skip to content

Instantly share code, notes, and snippets.

@regehr
Created November 4, 2019 04:02
Show Gist options
  • Save regehr/24560ea4352e11bf6c74a0bc70b8f0e1 to your computer and use it in GitHub Desktop.
Save regehr/24560ea4352e11bf6c74a0bc70b8f0e1 to your computer and use it in GitHub Desktop.
#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