Hatena::Grouptopcoder

naoya_t@topcoder RSSフィード

2008-12-04TZTester をどうにかするブーム

nitoyonさん,cafelierさんの改造を参考にしつつ

というかcafelier版をベースに改造

  • 実行時間を計測して表示
Test Case #0...PASSED (0.201 msec)
Test Case #1...PASSED (0.04 msec)
Test Case #2...FAILED (0.001 msec)
Expected: "728"
Received: "-1073744361"
Test Case #3...FAILED (0.002 msec)
Expected: "240249781"
Received: "-1073744409"
  • 返り値がdoubleの場合、期待値との差分が1e-9未満かどうかのチェックに差し替える

cafelier版とのdiff:

--- CFLCustom-TZTester.java	2008-12-04 04:01:21.000000000 +0900
+++ tangentz/TZTester.java	2008-12-04 05:51:06.000000000 +0900
@@ -32,7 +32,7 @@
     private static final String k_PROBLEM       = "$PROBLEM$";
     private static final String k_RUNTEST       = "$RUNTEST$";
     private static final String k_TESTCODE      = "$TESTCODE$";
-    private static final String k_VERSION       = "\n// Powered by TZTester 1.01 [25-Feb-2003] customized by cafelier";
+    private static final String k_VERSION       = "\n// Powered by TZTester 1.01 [25-Feb-2003] customized by cafelier, timer support by naoya_t";
     
     // Cut tags
     private static final String k_BEGINCUT      = "// BEGIN CUT HERE\n";
@@ -154,6 +154,13 @@
         TestCase[] Cases = m_Problem.getTestCases();
         StringBuffer Code = new StringBuffer();
 
+        // <<modified by naoya_t>> : timer
+        Code.append("#include <time.h>\n");
+        Code.append("clock_t start_time;\n");
+        Code.append("void timer_clear() { start_time = clock(); }\n");
+        Code.append("string timer() { clock_t end_time = clock(); double interval = (double)(end_time - start_time)/CLOCKS_PER_SEC; ostringstream os; os << \" (\" << interval*1000 << \" msec)\"; return os.str(); }\n");
+        Code.append("\n");
+
         // <<modified by cafelier>> : new test code template
 
         // Generate the vector output function
@@ -227,8 +234,13 @@
         Code.append("cerr << \"Test Case #\" << Case << \"...\"; ");
 */
         // Print "PASSED" or "FAILED" based on the result
-        Code.append("if (Expected == Received) cerr << \"PASSED\" << endl; ");
-        Code.append("else { cerr << \"FAILED\" << endl; ");
+		if (TypeString.equals("double")) {
+			Code.append("double diff = Expected - Received; if (diff < 0) diff = -diff; ");
+			Code.append("if (diff < 1e-9) cerr << \"PASSED\" << timer() << endl; ");
+		} else {
+			Code.append("if (Expected == Received) cerr << \"PASSED\" << timer() << endl; ");
+		}
+        Code.append("else { cerr << \"FAILED\" << timer() << endl; ");
 
         if (ReturnType.getDimension() == 0)
             {
@@ -264,6 +276,7 @@
 
         // <<modified by cafelier>> : new test code template
         Code.append("int Test_(Case_<" + Index + ">) {\n");
+        Code.append("\ttimer_clear();\n");
         // Generate each input variable separately
         for (I = 0; I < Inputs.length; ++I) {
             Code.append("\t");

FileEdit の CodeTemplate はこんな感じ:

$BEGINCUT$
/*
$PROBLEMDESC$
*/
$ENDCUT$

#line $NEXTLINENUMBER$ "$FILENAME$"
#include <string>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <algorithm>
$BEGINCUT$
#include <iostream>
#include "cout.h"
$ENDCUT$
#include <sstream>
#include <cmath>
using namespace std;

#define sz(a)  int((a).size())
#define pb  push_back
#define all(c)  (c).begin(),(c).end()
#define tr(c,i)  for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define rep(var,n)  for(int var=0;var<(n);var++)
#define found(s,e)  ((s).find(e)!=(s).end())
#define remove_(c,val) (c).erase(remove((c).begin(),(c).end(),(val)),(c).end())

class $CLASSNAME$ {
	public:
	$RC$ $METHODNAME$($METHODPARMS$) {
		
	}
};

$TESTCODE$

(間違えてJavaのやつを載せてました。C++のやつに差し替えました。12/5)

cout.h - デバッグ時にcoutに色々放り込むために

| 23:15 | cout.h - デバッグ時にcoutに色々放り込むために - naoya_t@topcoder を含むブックマーク はてなブックマーク - cout.h - デバッグ時にcoutに色々放り込むために - naoya_t@topcoder cout.h - デバッグ時にcoutに色々放り込むために - naoya_t@topcoder のブックマークコメント

#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
using namespace std;

ostream& operator<<(ostream &s, vector<string> v)
{
  int cnt = v.size();
  s << "[ ";
  for (int i=0; i<cnt; i++) {
	if (i > 0) s << ", ";
	s << '"' << v[i] << '"';
  }
  return s << " ]  // " << cnt << " item" << (cnt >= 2 ? "s" : "");
}

template <typename T> ostream& operator<<(ostream &s, vector<T> v)
{
  int cnt = v.size();
  s << "[ ";
  for (int i=0; i<cnt; i++) {
	if (i > 0) s << ", ";
	s << v[i];
  }
  return s << " ]  // " << cnt << " item" << (cnt >= 2 ? "s" : "");
}

template <typename T> ostream& operator<<(ostream &s, list<T> ls)
{
  int cnt = 0;
  s << "( ";
  for (typeof(ls.begin()) it=it.begin(); it!=it.end(); it++) {
	if (it != it.begin()) s << ", ";
	s << *it;
	cnt++;
  }
  return s << " )  // " << cnt << " item" << (cnt >= 2 ? "s" : "");
}

template <typename T> ostream& operator<<(ostream &s, deque<T> st)
{
  int cnt = st.size();
  s << "[ ";
  for (typeof(st.begin()) it=st.begin(); it!=st.end(); it++) {
	if (it != st.begin()) s << ", ";
	s << *it;
  }
  return s << " ]  // " << cnt << " item" << (cnt >= 2 ? "s" : "");
}

template <typename T1, typename T2> ostream& operator<<(ostream &s, map<T1,T2> m)
{
  int cnt = m.size();
  s << "{ ";
  for (typeof(m.begin()) it=m.begin(); it!=m.end(); it++) {
	if (it != m.begin()) s << ", ";
	s << it->first << " => " << it->second;
  }
  return s << " }  // " << cnt << " item" << (cnt >= 2 ? "s" : "");
}

template <typename T> ostream& operator<<(ostream &s, set<T> st)
{
  int cnt = st.size();
  s << "[ ";
  for (typeof(st.begin()) it=st.begin(); it!=st.end(); it++) {
	if (it != st.begin()) s << ", ";
	s << *it;
  }
  return s << " ]  // " << cnt << " item" << (cnt >= 2 ? "s" : "");
}

template <typename T1, typename T2> ostream& operator<<(ostream &s, pair<T1,T2> p)
{
  return s << "(" << p.first << "," << p.second << ")";
}