(Autotester) If you keep getting WA
Posted: Mon Aug 11, 2003 6:22 am
...and decided to post your code and ask for more test inputs/outputs, you will probably find this thing useful:
[cpp]
#include <cstdlib>
#include <fstream>
#include <iostream>
using namespace std;
class Autotester{
public:
virtual void generate_test(ofstream&) = 0;
virtual void run_test();
virtual bool check_if_results_matched(ifstream&, ifstream&);
};
/******** cfg section ********/
const int number_of_tests=100;
const char* ac_launch_command = "ac.exe <in.txt >out1.txt";
const char* wa_launch_command = "wa.exe <in.txt >out2.txt";
// if you need global variables,
// declare them here
class TestGeneratorAndChecker : public Autotester{
private:
// any data you need to generate tests
// and check results
public:
void generate_test(ofstream& out){
// this function will be called number_of_tests times;
// it must generate test data and write it to its parameter,
// which is associated with in.txt file
}
/* virtual bool check_if_results_matched(
ifstream& ac_result, ifstream& wa_result)
// after calling generate_test, Autotester
// passes generated input data to both programs by
// executing ac_launch_command and wa_launch_command;
// Autotester assumes that executing these commands
// will generate files out1.txt and out2.txt, containing
// AC program's and your program's output.
// After that, these files will be opened and passed
// to check_if_results_matched function.
// This function must compare these files and
// return true if they are equivalent.
// Default implementation should be overloaded
// only for problems with special correction program.
// if this function return false, Autotester will print
// "mismatch!" and exit, leaving test data in in.txt,
// AC program output in out1.txt and your program
// output in out2.txt
} */
};
/***** end of cfg section *****/
bool Autotester::check_if_results_matched(
ifstream& ac_result, ifstream& wa_result){
while(!ac_result.eof() && !wa_result.eof()){
if(ac_result.get()!=wa_result.get())
return false;
}
return (ac_result.eof()==wa_result.eof());
}
void Autotester::run_test(){
system(ac_launch_command);
system(wa_launch_command);
}
int main(){
randomize(); // in case someone'll forget...
Autotester* tester = new TestGeneratorAndChecker;
for(int i=0; i<number_of_tests; i++){
cout<<'.';
ofstream testfile("in.txt");
tester->generate_test(testfile);
testfile.close();
tester->run_test();
ifstream ac_result("out1.txt");
ifstream wa_result("out2.txt");
bool tmp =
tester->check_if_results_matched(ac_result, wa_result);
ac_result.close(); wa_result.close();
if(!tmp){
cout<<"\nmismatch!\n";
break;
}
}
delete tester;
}
[/cpp]
You can overload generate_test(ofstream&) and probably check_if_results_matched(ifstream&, ifstream&) and post them with your code. Then someone who is willing to help can place your program to wa.cpp, his/her accepted program to ac.cpp, that code above to tester.cpp (Java will probably require some code editing and modification of launch commands), compile them and generate/launch many tests with a single command (probably several hundreds random tests; useful if your program generates WA only in few very special cases which you cannot find). Takes far less time than re-reading problem statement, analysing your program, composing tests, typing them in and comparing outputs.
[cpp]
#include <cstdlib>
#include <fstream>
#include <iostream>
using namespace std;
class Autotester{
public:
virtual void generate_test(ofstream&) = 0;
virtual void run_test();
virtual bool check_if_results_matched(ifstream&, ifstream&);
};
/******** cfg section ********/
const int number_of_tests=100;
const char* ac_launch_command = "ac.exe <in.txt >out1.txt";
const char* wa_launch_command = "wa.exe <in.txt >out2.txt";
// if you need global variables,
// declare them here
class TestGeneratorAndChecker : public Autotester{
private:
// any data you need to generate tests
// and check results
public:
void generate_test(ofstream& out){
// this function will be called number_of_tests times;
// it must generate test data and write it to its parameter,
// which is associated with in.txt file
}
/* virtual bool check_if_results_matched(
ifstream& ac_result, ifstream& wa_result)
// after calling generate_test, Autotester
// passes generated input data to both programs by
// executing ac_launch_command and wa_launch_command;
// Autotester assumes that executing these commands
// will generate files out1.txt and out2.txt, containing
// AC program's and your program's output.
// After that, these files will be opened and passed
// to check_if_results_matched function.
// This function must compare these files and
// return true if they are equivalent.
// Default implementation should be overloaded
// only for problems with special correction program.
// if this function return false, Autotester will print
// "mismatch!" and exit, leaving test data in in.txt,
// AC program output in out1.txt and your program
// output in out2.txt
} */
};
/***** end of cfg section *****/
bool Autotester::check_if_results_matched(
ifstream& ac_result, ifstream& wa_result){
while(!ac_result.eof() && !wa_result.eof()){
if(ac_result.get()!=wa_result.get())
return false;
}
return (ac_result.eof()==wa_result.eof());
}
void Autotester::run_test(){
system(ac_launch_command);
system(wa_launch_command);
}
int main(){
randomize(); // in case someone'll forget...
Autotester* tester = new TestGeneratorAndChecker;
for(int i=0; i<number_of_tests; i++){
cout<<'.';
ofstream testfile("in.txt");
tester->generate_test(testfile);
testfile.close();
tester->run_test();
ifstream ac_result("out1.txt");
ifstream wa_result("out2.txt");
bool tmp =
tester->check_if_results_matched(ac_result, wa_result);
ac_result.close(); wa_result.close();
if(!tmp){
cout<<"\nmismatch!\n";
break;
}
}
delete tester;
}
[/cpp]
You can overload generate_test(ofstream&) and probably check_if_results_matched(ifstream&, ifstream&) and post them with your code. Then someone who is willing to help can place your program to wa.cpp, his/her accepted program to ac.cpp, that code above to tester.cpp (Java will probably require some code editing and modification of launch commands), compile them and generate/launch many tests with a single command (probably several hundreds random tests; useful if your program generates WA only in few very special cases which you cannot find). Takes far less time than re-reading problem statement, analysing your program, composing tests, typing them in and comparing outputs.