Hello, Codeforces!
If you tried to prepare some competitive programming problems, you might parse parameters like this:
#include "testlib.h"
#include <cstdlib>
using namespace std;
int main(int argc, char **argv) {
registerGen(argc, argv, 1);
int n = atoi(argv[1]);
int m = atoi(argv[2]);
int k = atoi(argv[3]);
...
Of course, such way has many disadvantages:
- You need to pass the exact amount of parameters, you cannot define default values for them.
- If you have many parameters, it's easy to forget the order.
- If you pass too few of the them, it will be undefined behavior.
So I developed a library called ParmPars to pass parameters to generators in a more convenient way. You can find it on GitHub. I hope it will help you to generate tests better.
Using ParmPars, you could rewrite the code above in the following way:
#include "testlib.h"
#include "parmpars.hpp"
using namespace std;
int main(int argc, char **argv) {
initGenerator(argc, argv, 1);
DECLARE(int, n);
DECLARE(int, m);
DECLARE(int, k);
...
In ParmPars, all the parameters are named, so to run the generator you can write something like
gen n=1 m=2 k=3
Let's write a simple generator for A+B problem using ParmPars: initGenerator
is a function that initializes both Testlib ad ParmPars. DECLARE
macros are used to declare a variable and init it from the parameters.
Of course, default parameters can be used:
#include "testlib.h"
#include "parmpars.hpp"
using namespace std;
int main(int argc, char **argv) {
initGenerator(argc, argv, 1);
DECLARE_D(int, n, 1);
DECLARE_D(int, m, 2);
DECLARE_D(int, k, 3);
...
Now if you run gen
without parameters, it will assume n=1
, m=2
and k=3
.
Using ParmPars in Polygon
Just upload it to Files > Resource Files.
More powerful example: generator ranges
Let's write a simple generator for A+B problem using ParmPars:
#include "testlib.h"
#include "parmpars.hpp"
using namespace std;
int main(int argc, char **argv) {
initGenerator(argc, argv, 1);
DECLARE_GEN(GenRange<int>, a);
DECLARE_GEN(GenRange<int>, b);
cout << a << " " << b << endl;
return 0;
}
Now we want to generate a test with two random numbers from 1 to 1000. Then, we can just use gen a=[1,1000] b=[1,1000]
. It works, because DECLARE_GEN
first reads [1,1000]
, and then converts it to int
by calling rnd.next(1, 1000)
. You can also append the generator seed as a last parameter: gen a=[1,1000] b=[1,1000] randomseed
.
More examples
You can find more examples in the project's README.
Questions
You can report the issues, ask questions about ParmPars and suggest enhancements in the comments. Obviously, you can also use GitHub's issue and pull request functionality.