Friday, September 13, 2013

Getting started with TopCoder Greed plugin

It may appear that there are already too many TopCoder arena plugins. The truth, however, is that there are as many preferences for work environments as there are coders. So new plugins will pop up all the time.

The Greed plugin was started last year, although few people seem to have heard of it. I only learned of it two days ago and by now already decided to switch to it. And this is coming from a guy who spent various hours and days working on tweaking KawigiEdit.

Why use the greed plugin?

If you intend to use an external editor, I think Greed is a good choice. Unlike some plugins out there, it doesn't require you to use 3 or 4 plugins at the same time to work at all. It is amazingly simple to set up.

It supports c++, python, Java and even that C# thing. Of course, it generates your code from a template, and also adds tester code to test all the examples automatically.

It is easy to get started with Greed. But it is also very customizable. That is the actual reason I switched to it. I have more control over the tester code than I ever had in KawigiEdit. Of course, what helped me made the switch was that I recently decided to start using KawigiEdit not for its internal editor but to allow an external editor - In my case, jEdit.

If you like coding from the Arena or if you use Visual Basic, then Greed will not help you. I'd suggest to stick to KawigiEdit.

Greed Setup

  • Download Greed's jar file. Latest version 1.5 is at: http://github.com/shivawu/topcoder-greed/tree/master/dist. However, I am not sure if future versions will be added there.
  • Start your topcoder arena.
  • Options\Editor
  • Click [Add]
  • Set the [Default] checkbox of the new entry for the Greed plugin to true. If you don't do this, you would have to manually select Greed after opening a problem.
  • Select Greed and click configure.
  • Type the path for a workspace. What is a workspace? You ask. It is just a folder that will store all the TopCoder code Greed generates for you. By default, it will save the files in sub-folders named after the SRMs. The workspace will also hold configuration and your custom templates. The good thing about this, is that setting up greed in another computer is the same as just copying the workspace and telling greed to use it.

Using Greed

Go to SRM 590 Div 1 practice room and open the 250 points problem.

 - Source code will be generated, "./SRM 590/FoxAndChess.cpp", in your workspace
 - I'm generating source code for you~
 - Using test template "res:/GCCTest.cpp"
 - Using source template "res:/Template.cpp"
 - Overriding "./SRM 590/FoxAndChess.cpp", old files will be renamed
 - All set, good luck!
 -

So, let's open FoxAndChess.cpp.

#include <cstdio>
#include <cmath>
#include <cstring>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <set>
#include <vector>
#include <sstream>
#include <typeinfo>

using namespace std;

class FoxAndChess {
    public:
    string ableToMove(string begin, string target) {
        return "";
    }
};

// CUT begin
template <typename T> string pretty_print(T t) { stringstream s; typeid(T) == typeid(string) ? s << "\"" << t << "\"" : s << t; return s.str(); }

bool do_test(string begin, string target, string __expected, int caseNo) {
    cout << "  Testcase #" << caseNo << " ... ";

    time_t startClock = clock();
    FoxAndChess *instance = new FoxAndChess();
    string __result = instance->ableToMove(begin, target);
    double elapsed = (double)(clock() - startClock) / CLOCKS_PER_SEC;
    delete instance;

    if (__result == __expected) {
        cout << "PASSED!" << " (" << elapsed << " seconds)" << endl;
        return true;
    }
    else {
        cout << "FAILED!" << " (" << elapsed << " seconds)" << endl;
        cout << "           Expected: " << pretty_print(__expected) << endl;
        cout << "           Received: " << pretty_print(__result) << endl;
        return false;
    }
}

bool run_testcase(int __no) {
    switch (__no) {
        case 0: {
            string begin = "R...";
            string target = "..R.";
            string __expected = "Possible";
            return do_test(begin, target, __expected, __no);
        }
        case 1: {
            string begin = "..R.";
            string target = "R...";
            string __expected = "Impossible";
            return do_test(begin, target, __expected, __no);
        }
        case 2: {
            string begin = ".L.R.R.";
            string target = "L...R.R";
            string __expected = "Possible";
            return do_test(begin, target, __expected, __no);
        }
        case 3: {
            string begin = ".L.R.";
            string target = ".R.L.";
            string __expected = "Impossible";
            return do_test(begin, target, __expected, __no);
        }
        case 4: {
            string begin = "LRLLRLRLLRLLRLRLRL";
            string target = "LRLLRLRLLRLLRLRLRL";
            string __expected = "Possible";
            return do_test(begin, target, __expected, __no);
        }
        case 5: {
            string begin = "L";
            string target = ".";
            string __expected = "Impossible";
            return do_test(begin, target, __expected, __no);
        }

        // Your custom testcase goes here
        case 6:
            break;
        default: break;
    }
    return 0;
}

int main(int argc, char *argv[]) {
    cout.setf(ios::fixed,ios::floatfield);
    cout.precision(2);
    cout << "FoxAndChess (250 Points)" << endl << endl;

    int nPassed = 0, nAll = 0;
    if (argc == 1)
        for (int i = 0; i < 6; ++i) nAll++, nPassed += run_testcase(i);
    else
        for (int i = 1; i < argc; ++i) nAll++, nPassed += run_testcase(atoi(argv[i]));
    cout << endl << "Passed : " << nPassed << "/" << nAll << " cases" << endl;

    int T = time(NULL) - 1379094076;
    double PT = T / 60.0, TT = 75.0;
    cout << "Time   : " << T / 60 << " minutes " << T % 60 << " secs" << endl;
    cout << "Score  : " << 250 * (0.3 + (0.7 * TT * TT) / (10.0 * PT * PT + TT * TT)) << " points" << endl;
    return 0;
}
// CUT end

As you can see, Greed generated just about everything you need to begin coding in some editor. Open the file in some editor , you probably need something to compile it and run it. I use some shell scripts. The output looks like this by default:

FoxAndChess (250 Points)

  Testcase #0 ... FAILED! (0.00 seconds)
           Expected: "Possible"
           Received: ""
  Testcase #1 ... FAILED! (0.00 seconds)
           Expected: "Impossible"
           Received: ""
  Testcase #2 ... FAILED! (0.00 seconds)
           Expected: "Possible"
           Received: ""
  Testcase #3 ... FAILED! (0.00 seconds)
           Expected: "Impossible"
           Received: ""
  Testcase #4 ... FAILED! (0.00 seconds)
           Expected: "Possible"
           Received: ""
  Testcase #5 ... FAILED! (0.00 seconds)
           Expected: "Impossible"
           Received: ""

Passed : 0/6 cases
Time   : 11 minutes 25 secs
Score  : 217.08 points

(Of course, when you pass a test case it will tell you it is correct, and the time it took to run). It is nice that it also tells you the time since you opened the problem and estimates the score you'll get in TopCoder (Assuming it is not a resubmit, and that the file was generated at the same time as you opened the problem).

When you click [Compile] or [Save] in the Topcoder arena, everything between // CUT begin and // CUT end will be automatically removed from the submission, everything else will be sent to topcoder.

What is cool about this is that you can customize it and do some cool things using the configuration and templates option. I'll give more details and share my tester templates in a later blog post, but you can read Greed's wiki for more information.

No comments :