/** * Generate the actual code from problem object */ std::string CppCode::generateCode(Problem& problem) { //All header file list std::string theCode = this->cppHeaderfiles(); theCode += std::string("\n#define Zclr(arr) memset(arr, 0, sizeof(arr))\n") + "#define Nclr(arr) memset(arr, -1, sizeof(arr))\n" + "#define M31 1<<30\n" + "#define Pi (2.0*acos(0.0))\n" + "#define Eps (1e-9)\n"+ "#define Rep(_var, _N) for (int _var=0; _var<_N; _var++ )\n"+ "#define For(_var, _S, _N) for (int _var=_S; _var<=_N; _var++ )\n\n"; theCode += "class "+problem.getClassName()+" {\n" + "public:\n"+this->methodCode(problem.getMethod()) + "};\n\n"; //end of class code theCode += "// <editor-fold defaultstate=\"collapsed\" desc=\"Generated Code\">\n"; theCode += "namespace otocoder {\n" + this->generateOutputComparison(problem.getMethod()->getReturnVariable())+ this->generateRunTest() + this->generateFormatResult(problem.getMethod()->getReturnVariable()) + this->generateVerifyCase(problem) + this->generateRunTestCase(problem) + this->generateFullTestReader(problem)+ "}\n\n"; theCode += this->generateDefaultMain(); theCode += "// </editor-fold>\n"; return theCode; }
std::string CppCode::generateRunTestCase(Problem& problem) { std::string mCode; mCode = " int run_test_case(int casenum) {\n"; mCode += " switch (casenum) {\n"; char arr[200]; // Generate the individual test cases int totalCases = problem.getSampleTestSize(); for (int i = 0; i < totalCases; ++i) { sprintf(arr, " case %d: {\n", i); mCode += arr; mCode += this->generateTestCase(i, problem.getClassName(), problem.getMethod(), problem.getSampleTestCaseAt(i)); mCode += " }\n"; } // next mCode +=std::string(" default:\n") + " return -1;\n" + " }\n" + " }\n\n"; return mCode; }
std::string CppCode::generateFullTestReader(Problem& problem) { Method* method = problem.getMethod(); Variable* var; std::string code = tabStr + "const std::string currentDateTime() {\n"+ tabStr + tabStr + "time_t now = time(0);\n"+ tabStr + tabStr + "struct tm tstruct;\n"+ tabStr + tabStr + "char buf[80];\n" + tabStr + tabStr + "tstruct = *localtime(&now);\n"+ tabStr + tabStr + "strftime(buf, sizeof(buf), \"%Y-%m-%d %X\", &tstruct);\n"+ tabStr + tabStr + "return buf;\n"+ tabStr+"}\n\n"+ tabStr+"//This method will only accept input files that are formatted in proper way.\n"+ tabStr+"//Command line example: "+problem.getClassName()+".exe -2 <"+problem.getClassName()+".io\n"+ tabStr+"bool run_full_test() {\n" + tabStr+tabStr+"int testCase, N, caseNo, correct=0;\n"; //declare all variables for (int i=0; i<method->getNumberOfParameters(); i++) { var = method->getParameterAt(i); code+= tabStr+tabStr+this->generateDatatype(var)+" "+var->getName()+";\n";//vector<int> var; //if we have an array then we will create another variable to read single item of that array, redundant but easy to code :| if (var->isArray()) { code += tabStr+tabStr+this->convertDataType(var->getDataType())+" "+var->getName()+"_sin;\n"; //with _in suffix } } var = method->getReturnVariable(); code+= tabStr+tabStr+this->generateDatatype(var)+" "+var->getName()+";\n";//vector<int> var; if (var->isArray()) { code += tabStr+tabStr+this->convertDataType(var->getDataType())+" "+var->getName()+"_sin;\n"; //with _in suffix } code += "\n"; code+= tabStr+tabStr+"std::cin>>testCase; std::cin.ignore(10, '\\n');\n" + tabStr+tabStr+"for (int i=0; i<testCase; i++) {\n" + tabStr+tabStr+tabStr+"std::cin>>caseNo; std::cin.ignore(10, '\\n');\n"; //code to read all parameters for (int i=0; i<method->getNumberOfParameters(); i++) { code += this->generateSingleCaseReader(method->getParameterAt(i), tabStr+tabStr); } //code to read expected result code += this->generateSingleCaseReader(method->getReturnVariable(), tabStr+tabStr); //code to run class.Method(parameters...) code += tabStr+tabStr+tabStr+"clock_t start_ = clock();\n"; code += tabStr+tabStr+tabStr+this->generateDatatype(method->getReturnVariable())+" received_ = " + problem.getClassName()+"()."+method->getName()+"("; for (int i=0; i<method->getNumberOfParameters(); i++) { if (i) { code += ", "; } code += method->getParameterAt(i)->getName(); } code += ");\n"; code += tabStr+tabStr+tabStr+"correct += verify_case(caseNo, " + method->getReturnVariable()->getName() + ", received_, clock()-start_);\n"; code+=tabStr+tabStr+"}//end of testCase for loop\n\n"; code += tabStr+tabStr +"if (testCase == 0) {\n" + tabStr+tabStr+tabStr+"cerr << \"No test cases run.\" << endl;\n" + tabStr+tabStr+"} else if (correct < testCase) {\n"+ tabStr+tabStr+tabStr+"cerr << \"Some cases FAILED (passed \" << correct << \" of \" << testCase << \").\" << endl;\n"+ tabStr+tabStr+"} else {\n"+ tabStr+tabStr+tabStr+"cerr << \"All \" << testCase << \" tests passed!\" << endl;\n"+ tabStr+tabStr+tabStr+"std::ofstream ofs(\""+problem.getClassName()+".st\", std::ios_base::app);\n"+ tabStr+tabStr+tabStr+"ofs<<currentDateTime()<<std::endl;\n"+ tabStr+tabStr+tabStr+"ofs.close();\n"+ tabStr+tabStr+"}\n"+ tabStr+tabStr+"return true;\n"+ tabStr+"}\n\n"; return code; }