Showing posts with label arenaplugin. Show all posts
Showing posts with label arenaplugin. Show all posts

Thursday, June 12, 2014

*Taunts you*

In today's SRM 624 there was a problem that asked you to return something modulo 1000000009. Usually the modulo is 1000000007 or 1000000009 , but people have the impression it is 1000000007 most of the time.

Usually topcoder example tests in this kind of problem include a test case that makes use of the modulo. This is intentional so that people can catch a mistake in writing this constant. Unfortunately, today's problem didn't have such test case.

I didn't even notice. If you read my recap of SRM 624 you will see I even mistakenly used 1000000007 when typing the explanation. And yet I passed , well I have a secret weapon (not so secret).

This is my Greed c++ template:

#include <bits/stdc++.h>
// ${Contest.Name} - ${ClassName} (${Problem.Score} points) by vexorian
using namespace std;

struct ${ClassName}
{
${<if Problem.Description.Modulo}
    const int MOD = ${Problem.Description.Modulo};

${<end}
    ${Method.ReturnType} ${Method.Name}(${Method.Params})
    {
        return ${if Method.ReturnType.Array}{}${else}${Method.ReturnType;zeroval}${end};
    }
};

${CutBegin}
${<TestCode}
${CutEnd}

Take a look to the if Problem.Description.Modulo part. Yes, this part of my template actually generates the MOD constant for me :). One day I spent an afternoon or so making the Greed topcoder plugin able to parse the modulo constant and make it accessible to templates. This is why :).

Sunday, May 18, 2014

Auto-test Topcoder problems with multiple correct answers

Topcoder have been improving the decade old contest system a bit. Things like allowing larger constraints, possibility of different time/memory limit per problem, etc. But the greatest change of them all, the one that actually brings problem variety rather than Fake Difficulty is that some problems allow multiple correct answers.

The first SRM to have these problems was SRM 617. The division 2 easy and division 1 medium allow multiple correct answers. They were interesting problems that would not have worked quite as well without this ability.

In SRM 617 div2 medium, you have to return two composite numbers that add up to `n`. `n` is at least 20 and at most 1000. It turns out there is a very cool and easy solution: Return `(4, n-4)` if `n` is even, else `(9, n-9)` if `n` is odd. But if this problem appeared in old topcoder, how would we have led coders to this solution? We would have had to specify tons of things. Like, the first integer must be the smallest composite possible that makes the result as intended. But then there would be odd cases in which `(4, n-4)` is an answer, and then the solution would be more complicated (not appropriate for div2 easy). Even if we did all that, the problem wouldn't be very nice, because the results of the example cases's results would give the solution away too easily...

However, the bad thing about these new problems is that, it is Topcoder, and many of us are used to Topcoder Arena plugins that generate automatic testers based on the example test cases. If we used our old arena plugins on these problems and the correct results of our solution didn't exactly match the expected solutions, the automated tester would tell us that the results are wrong. Even when they are actually right. We need some changes.

So after SRM 617 I made plans to work as hard as possible in making my Greed tester setup able to work around this a bit. This is the story.

Identifying those problems

The first thing to do is to identify the problems that allow multiple correct answers for a test case. This requires help from the Topcoder Arena developers. The first thing I did was, during SRM 617 I told admins to remember that arena plugin API needs a way to detect this. Then I waited, and waited. Then I figured, there is a thread I know that seems to be monitored closely by Arena developers. Making post in this thread seems to be the only way I have to contact them, and so I did. I really the plugin API was documented at all and that each change was announced and explained and all new methods were known. But this is not the case. Even after receiving confirmation that this feature was in the API, I had to dig through the Jar looking for something that might be it.

problem.getComponent().isCustomChecker();
// where problem is com.topcoder.client.contestant.ProblemComponentModel

So now I just needed to add the feature to Greed so that any template was able to identify these problems and then we can do the magic.

I made a pull request, that PR adds a Problem.HasCustomChecker field. You can use it in templates: ${if ProblemHasCustomChecker}...${end} . The Pull request is still not merged and thus you will have to do some magic to compile greed using it. If you want...

Modifying the tester templates

We also need to modify the tester so that it can make use of this information. But how?

My idea of how to allow automated testers in these problems consists of two parts:

  • My tester already supports test results in which it is not known whether or not the returned answer is correct. And it can already report results as such (Using a ? symbol). Testing is still useful because you can get the results for all examples with a single run and you can also detect any example that times out or has a runtime error. So the first idea is to make the generated test code to make all test cases do this when the problem has this flexibility.
  • However, that doesn't fix that maybe the coder wants/needs also to detect wrong answers. The only workaround to this is to allow user to code a checker method for the returned output.

In many problems, it is easier to check if an output is correct than to solve the problem. For example, the problem I described above. It is easy to check that the returned value is a pair of integers, that they are both positive, they add up to n and they are composite. So we can make a tester.

In other problems, it may not be so easy to know if a result is correct without solving the problem. But if you already know one correct result for that input, then it is still easy to write a grader. For example. A problem that returns the shortest sequence following some conditions. If you know that the provided example case result gives a 3 elements sequence, then we can tell that any sequence with more than 3 elements is wrong and can report as such making use of this result.

My idea is to have a checker method in the problem class. It should take input, resulting output and the example' expected output (if it exists) If checker method returns 0, then it is not known if the provided answer is correct. If return -1, we know it is wrong and if it is 1, we know it is correct. Initially, this method returns 0 in all cases, but it can be modified by the user.

I implemented this in python, it looks like this:

class SilverbachConjecture:
 def solve(self, n):
    if n % 2 == 0:
        return (4,n - 4)
    else:
        return (9,n - 9)

# CUT begin
#-------------------------------------------------------------------------------
 def greedCheckResult(self, testInput, returnedAnswer, expectedAnswer):
    (n,) = testInput
    #You can implement a custom checker.
    # Return value: -1 is WA, 0 is unknown and 1 is AC.
    # expectedAnswer is not None, then expectedAnswer is a known correct answer.
    if len(returnedAnswer) != 2:
        return -1
    (a,b) = returnedAnswer
    if (a + b != n) or (a <= 0) or (b <= 0):
        return -1
    
    def isComposite(x):
        p = 2
        while p*p <= x:
            if x % p == 0:
                return True
            p += 1
        return False
        
    return 1 if isComposite(a) and isComposite(b) else -1

The trick is that the generic tester is a separate file, but I just updated it a bit to detect if a greedCheckResult method exists, if it does, then it does the required logic.

I am not sure yet how to do this in c++, yet, but I should try something tomorrow.

Besides of modifying the generic tester, I also modified my python template. This is the part that makes use of the HasCustomChecker field:

# ${Contest.Name} - ${ClassName} (${Problem.Score} points) by vexorian :

${<if Problem.Description.Modulo}
MOD = ${Problem.Description.Modulo}

${<end}
class ${ClassName}:
 def ${Method.Name}(self, ${Method.Params}):
    return ${Method.ReturnType;zeroval}
${<if Problem.HasCustomChecker}


${CutBegin}
#-------------------------------------------------------------------------------
 def greedCheckResult(self, testInput, returnedAnswer, expectedAnswer):
    (${Method.Params},) = testInput
    #You can implement a custom checker.
    # Return value: -1 is WA, 0 is unknown and 1 is AC.
    # expectedAnswer is not None, then expectedAnswer is a known correct answer.
    return 0

${CutEnd}
${<end}

${CutBegin}
${<TestCode}
${CutEnd}

The relevant changes to the generic tester affect only the run_tests function:

def run_testcase( problemClass, methodName, testInExpected, caseNo, totalCase, testTimeOut, finalLines, compactMode ):
    (testIn, expected) = testInExpected # so that it compiles in python3
    if compactMode != ONLY_REPORT: 
        sys.stdout.write(TEST_COLOR + "Test " + str(caseNo) + COLOR_RESET + ": " + prettyStr(testIn)+"\n")
    startTime = time.time()
    instance = problemClass()
    exception = None
    try:
        result = getattr(instance, methodName)(*testIn);
    except Exception as e:
        ln = None
        for x in traceback.extract_tb(sys.exc_traceback):
            if x[0] == problemClass.__name__+'.py':
                ln = x[1] 
        if ln is None:
            exceptionShort = '%s, (unknown line)'%( type(e).__name__ )
        else:
            exceptionShort = '%s, line: %d'%( type(e).__name__, ln )
        exception = traceback.format_exc()
        
    elapsed = time.time() - startTime   # in sec
    if compactMode != ONLY_REPORT:
        sys.stdout.write("Time: %.02f seconds.\n" % elapsed)

    knownAnswer = (expected is not None)
    if exception is not None:
        if compactMode != ONLY_REPORT:
            sys.stdout.write("RUNTIME ERROR: \n")
            sys.stdout.write(exception)
        correct = False
    else:
        if hasattr(instance, 'greedCheckResult'):
            check = instance.greedCheckResult(testIn, result, expected)
            correct = (check >= 0)
            knownAnswer = (check != 0)
        else:
            correct = expected is None or tc_equal(expected, result)
        if compactMode != ONLY_REPORT:
            if not correct or not knownAnswer:
                sys.stdout.write("Desired answer:\n")
                sys.stdout.write("\t%s\n" % prettyStr(expected) )
            sys.stdout.write("Your answer:\n")
            sys.stdout.write("\t%s\n" % prettyStr(result) )
    
    res = '?'
    if exception is not None:
        res = 'E'
    elif not correct:
        res = 'X'
    elif elapsed > testTimeOut:
        res = 'T'
    elif knownAnswer:
        res = '+'
    
    # final lines:
    s = ( TEST_COLOR + "t" + prettyCase(caseNo, totalCase) + COLOR_RESET + ": " + colorTestResult(res) )
    s += (" (%.2fs)" % elapsed)
    if res in ('?', 'X'):
        s += (" (" + prettyStr( result)+ ")" )
    elif res == 'E':
        s += (" " + exceptionShort)
    finalLines.append(s)

    if compactMode != ONLY_REPORT:
        sys.stdout.write(" %s\n" % colorTestResult(res) )
        sys.stdout.write( BAR_COLOR + ('='*BAR_LENGTH) + COLOR_RESET + "\n")
    return res

I'll eventually make a more formal release of this update once the field is added to the official Greed and I figure out a clean way to do this in c++.

Sure , it is possible that the checker you implement has a bug and thus it reports your results as correct when they are not, you submit and fail system tests. But it is better than nothing.

Victory (for now):

Tuesday, January 07, 2014

Greed 2.0 release candidate

When this was released I was super busy with the SRM 602 editorial to share it. But now I am not so busy (although I am making SRM 603's editorial as we speak). Let me take a break and talk about the final feature list for 2.0. No more features will be added to 2.0, the rc is only to detect bugs.

Flexible Templates

Greed 1.6 was cool and I liked it, but 2.0 is far more powerful because of what it did to the templates. In 1.6 you could only modify two templates : source (source code file), test (the tester put inside the source code file) and maybe unit tests for java and csharp. This made Greed just slightly more powerful that the other plugins. The new Greed though, can be programmed to create any custom file/sections of files for you using any template you add. Each template is a powerful script that makes it easy to build anything using information from the problem and contest. For example, Greed by default will make some templates:

  • source: (same as before)
  • filetest: New version of the tester, saves the test cases in an external file, so you can edit this external file to add new test cases.
  • testcase: The text file that contains all the test cases .
  • problem-desc: The problem statement in cool HTML format.

So by default Greed will already do pretty much anything you'd expect from a topcoder plugin. Will generate a source code file for you, with automated testing of the example cases and an ability to add new test cases. It will also generate and store in disk a version of the problem statement.

However, what's new is that you can modify / change all of this. You can add new files to test. You can replace the files that are created or the templates used for them. For example, by replacing the filetest template with the test template, it will use another kind of tester that doesn't use a text file to store the test cases and instead has them stored as code.... Or, you could use the [dualcolor templates]. Very advanced testers for c++ and python that I developed and do tons of amazing things...

Create makefiles, project files for IDEs, separate source code and tester, store the problem's memory limit in some file so you can tell your testing environment to enforce it. it is all up to your needs and creativity.

Template options

With the advent of custom templates, the need to configure them became very important. There is a difference between the plugin and the templates. So hardcoding configuration options for the templates in the plugin wouldn't work too well. Instead, we added a way to allow templates to declare configuration options and the configuration file can write them.

Basically , the template definition in config file has an .options {} section, each option is a String field that is read by the template, this enables the following features.

Multi-process tester in c++

All the 3 c++ testers available have the option to work in multiprocess. Which means that they will call a different instance of the program's process to test each example case. This makes testing more accurate if your program uses global variables. It also allows the testing to continue even after a runtime error in an early example. The runtime error is also reported.

Problem statement themes

The problem statement template is very useful and can be customized through template options. The most important customization is the color theme:

It is also possible to customize the CSS either by adding an extra file or by replacing the style completely. Of course, since the problem statement is a template, you can also change everything about it.

I personally use the Stylish firefox plugin

Hooks

You can now set a program to run automatically whenever a template is created. I currently have a trigger template that is created automatically whenever I open a problem. The trigger causes firefox to open the problem statement and jEdit to open the source code ^^

Aids to make folder organization better

I added something that allows the code to be placed in better-organized folders. I currently programmed my Greed to put all TCO problems in a folder, and split the SRMs in groups of 25. It is very useful and much better to me than having all problems in the same folder, or a single folder for each SRM.

Aware of time and memory limits

Greed is the only plugin I know of that actually knows of the per-problem memory and time limits. It uses them for the problem statement, but your custom templates can also make use of them. My tester uses the time limit, for example.

Modulo detection

This is so useful: http://vexorian.blogspot.com/2013/11/bragging-about-incoming-greed-features.html

How to get it

Greed 2.0 release candidate: in release page. It has a couple of minor HTML bugs ashawat just found, if you don't like those bugs, you can fetch the source code from git and compile. Speaking of which, I have a version of Greed in my github fork that sets up my prefered settings by default (The folder organization, the dark gray HTML template and my testers): https://github.com/vexorian/topcoder-greed

Thursday, January 02, 2014

Per problem memory and Time limits in Greed

Greed (at least the git version) is now the first plugin to support the per problem memory and time limits that were recently added to topcoder.

I had to cry for help from the arena maintainers to get this to work. I discovered many things I didn't know about the arena API, for example, the Memory limit thing was in it since years ago (huh?). Anyway, I finally got it to work. That was quite a pull request...

Why did I care so much to get this to work? Well, if some TC problems are going to have a custom memory and time limit, you need to know. Currently I am reading problem statements generated by greed instead of those by the arena (it is much better!), so I need them to contain this information. There is also something else though...

My test system is basically just a runcpp.sh script that sets things up correctly and puts the default Memory Limit (256) and runs things. Then it calls the Greed-generated source code file, which has a time limit feature. So my current TopCoder environment makes quite some use of these limits. If a problem gets new limits, they would break without using this information.

Making the environment take advantage of this feature was another issue. For time limit, it was relatively easy, my tester templates already had a time limit constant. I just modified them to use a time factor instead of set limit. My templates are now an official part of greed and you can find more info at: https://github.com/shivawu/topcoder-greed/tree/master/src/main/resources/templates/dualcolor

The memory limit was an adventure of its own. Memory limit was enforced by the runcpp.sh (and similar) scripts I used. But now there was a custom ML per problem. I first needed to store that information somewhere. I am not sure if this was the simplest way possible, but what I did was add yet-another template to greed. The memory-limit template:

    memory-limit {
        overwrite = force
        outputFileName = "limit/${Problem.Name}.txt"
        templateFile = "limittemplate.txt"
    }

(You also need to add memory-limit to the templates line). This would make greed generate a file ProblemName.txt at a limit sub-folder of the contest folder... The template file is just this:

${Problem.MemoryLimitMB}

So this txt file just contains the memory limit in MB.

Next step was to make the runcpp.sh script able to read this txt file (if it exists). The same with the python and Java ones. Posting the Java one for reference as it is the easiest to understand (The other ones need to do far more complicated things like calling ulimits and multiplying the MB limit by 1024...):

#!/bin/bash
#default
LIMIT_MB=256

#extract folder name from $1:
DIR=$(dirname $1)
#extract file name (problem name) from $1:
PROBLEM=$(basename $1)
PROBLEM=${PROBLEM%%.*}
#build the limit file name
LIMIT=$DIR/limit/$PROBLEM.txt
if [ -f $LIMIT ]; then
#echo "READ MEMORY LIMIT"
LIMIT_MB=`cat $LIMIT`
#else
#echo "NO MEMORY LIMIT, USE DEFAULT"
fi
#echo "MB = " $LIMIT_MB

echo "compiling..."
javac $1.java
if [ $? = 0 ];
then
java -Xmx${LIMIT_MB}m $1
fi

The trick is to modify the java command line, to use -Xmx${LIMIT_MB}m, where LIMIT_MB contains the read memory limit value.

So?...

I just hope that problems with custom memory limits are not too rare to justify all this work.

I am liking greed more and more every day. Nowadays I consider Greed not to be a TopCoder arena plugin, but an arena plugin workshop. The workshop just happens to come with an example simple arena plugin by default :)

The arena plugin survey

Calling all Greed users (and any other plugin users too). It is best to get surveyed in the plugin survey at : http://apps.topcoder.com/forums/?module=Thread&threadID=807988&start=0 I already made a post for Greed, so if you use it, plus that post.

Sunday, December 29, 2013

A white whale defeated

I have wonderful news! (for me mostly), I have defeated a major white whale of mine. A bug that has annoyed me since ages ago, but has become a personal vendetta just recently. Have you ever noticed that problem statements in the topcoder statistics site sometimes have way more line breaks than in the arena?

Try the SRM 602 div1 hard BlackBoxDiv1 , for example. This is how it looks like in the statistics: http://community.topcoder.com/stat?c=problem_statement&pm=12923. Now try it in the arena, it is much better there.

It has become a bigger issue when the Greed plugin added problem statement support. Its ability to automatically generating problem statement HTML was something I never thought I needed, until I started using it. It is so useful for editorials to be able to read statements without having to navigate topcoder's site! It also allows much control in the way the statement looks, making things easier on your eyes. But of course, the same bug that happens in the statistics problem statements happened in Greed's problem statements.

It is a very strange bug that happens only in some problem statements (strangely (Now I know it was not so strange), it always happens with *my* problems). So for long I was clueless as to what causes it or how to fix it. I even tried to write a thread about it asking for help from anyone who could decode this mystery.

Tonight, I was messing with some other bits of the problem statement, when I noticed something funny about how firefox shows source code... It painted some </br> closing tags red. This is something I never bothered to pay attention to before, but tonight it finally hit me: Topcoder statements seem to use XHTML. I know at least that some XML is used in topcoder. Usually if you use the <br> (line break) tag, the problem statement editor would convert it to <br></br> (and thus close the tag). However, when you use HTML , browsers consider a </br> tag as nonsense that probably means <br>... This causes them to add an extra line break :).

So, just rushed to Greed's source code and added a tweak to replace <br></br> patterns with <br/>. Build the plugin , test, and voila!

Before BR fix:


After BR fix:

Cool!

I know what you are wondering: Does this mean that Greed is better at generating problem statements than TopCoder's own site? - The answer is yes.

Saturday, December 21, 2013

TopCoder folder organization TAKE TWO

Some time ago I talked about how I made a script to be able to organize TopCoder problem source codes by automatically creating a folder for each contest. But some time after that I had to desist of using this folder organization, because TopCoder contests have different names during the match and when in the practice room ! (During the contest, it is Single Round Match XXX, the practice room is SRM XXX). So if I used Greed to organize my problems like that, I would have to always move my code from a folder to another after every match. And that's annoying.

After that, the hindrances of having all problem source codes in the same folder became more and more noticeable to me. However, I also reckoned that a folder per contest was not so great, either, too many folders. Both approaches return in the main folder having too many children. My dream solution was something of a hybrid. Separating SRMs in groups of 25 SRMs, TCO problems in one folder, TCHS folders in another, TCCC in another. And also a folder for the remaining contests. There are a few of odd contests that don't belong to those categories and we don't really need a whole category or folder for each of them.

Modifying Greed

The first step of making this work is to make the arena plugin do it. After some hacking and some convincing I managed to get the code to do exactly that into the current git version. It will be officially in whatever next release is (second beta? Official Greed 2.0? Who knows?. But you can just compile Greed from its github right now if you want this.

What I did was to create a complex helper Class to render Contest names using very special rules. Basically, you modify Greed.conf and add:

  codeRoot = "${Contest;category(srm=25)}"

This instructs Greed to change the codeRoot folder to a special kind of name. By default, codeRoot is exactly equal to the contest name found out by Greed, but with this modification, it will be equal to "TCO" if the contest name contains "TCO" or "Topcoder open". Or if the contest name is "SRM XXX" or "Single Round Match XXX", the folder name will be "SRM a-b", where a-b is a interval that contains 25 SRMs. E.g. "SRM 400-424". Of course, if you change the srm=25 with srm=100, the number of SRMs per interval changes. Here you can find a detailed explanation of what ;category does.

Moving problems

The old problems were in a single topcoder folder containing them all. Now that greed uses the folder structure I wanted it to use, I still need to move previous problems to the correct folders.

The first issue was getting a problem's contest name automatically. I solved this little problem with the folder organizer script I posted a while back. Now all the problems are inside folders with names equal to topcoder contests. But I still needed to re-organize these folders...

So I made another script:

# Topcoder folder organizer 
#
# err let us say it is released under the zlib/libpng license
# http://www.opensource.org/licenses/zlib-license
# (c) Victor Hugo Soliz Kuncar, 2011
#
#
import urllib, re, sys, os, time, string, glob

def fixContest(result):
separate = 25
if 'TCHS' in result:
result = 'TCHS'
elif 'TCCC' in result:
result = 'TCCC'
elif re.match( ".*(TCO|(top\s*coder\s*open)).*" , result, flags=re.IGNORECASE):
result = 'TCO'
elif re.match( ".*(SRM|single\s*round\s*match)\s*(\d+).*" , result, flags=re.IGNORECASE):
num = re.match( ".*(SRM|single\s*round\s*match)\s*(\d+).*" , result, flags=re.IGNORECASE).group(2)
#print '{%s}' % num4
num = int(num)
a = num - num % separate
b = a + separate - 1
result = 'SRM %d-%d'%(a,b)
else :
result = 'Other'
return result


def inFolder():
os.chdir("./")

for dirname, dirnames, filenames in os.walk('.'):

# print path to all filenames.
for filename in filenames:
if dirname != '.':
contest = './'+fixContest(dirname[2:])
if not os.isdir(contest):
os.mkdir( contest )
os.rename( os.path.join(dirname,filename), os.path.join( contest, filename) )


inFolder()


What the script does is take each folder in the current work directory ( ./ ) and for each folder, get the contest category (Same as ;category("srm=25") in Greed) (You can change the separate variable in the script from 25 to something else). And move the files inside the folder to the better category.

That's it

Thanks to the modifications of Greed and the two scripts, I have a neatly organized topcoder folder. Note that because of ;category, no matter if a contest is named "Single Round Match XXX" or "SRM XXX", the result is the same.

Thursday, December 19, 2013

Setting up Topcoder Greed plugin with your fav. IDE (Code::blocks)

I always talk about the Greed plugin, it is just so customizable. It is hard to measure the power it has. From its simple default setup to what I am going to introduce you to in this post. In this post, we are going to make Greed create a Code::blocks work environment and call code::blocks automatically whenever you open a problem. I hope this example can be adapted also for other IDEs.

This post is about Greed 2.0, which is currently in beta. And not just beta Greed 2.0, but possibly the latest in git, I hope greed can have a jar release soon, but for now you'll need to get it from github and compile it. Basically you just download the contents of the repository and use ./gradlew fatjar to compile it and make a jar for you which will be saved in the build/libs folder

Fiddling with the IDE

In a first step, let's learn all that is needed about the compiler and how to set it up. Open some problem in Greed. My favorite test subject is the problem TBlocks from the TCO13 championship round. After you open it in greed, assuming you are with default config, it will create 3 files in a specific folder in your Greed work folder.

  • TCO 2013 Finals/TBlocks.cpp
  • TCO 2013 Finals/TBlocks.sample
  • TCO 2013 Finals/TBlocks.html

In greed 2.0, the default behavior is to save example data in the .sample file. The .cpp file then has to read from this .sample file, and the .sample file has to be in the command's work folder when you run the compiled program. While the ability to save examples in a separate file is cool, I disagree with this as a default, I think it complicates things too much. It is possible to change this behavior, but for the matter of this tutorial it will be a good thing, because I am teaching you how to make it all work in your IDE.

Let's create a Code::blocks project that runs this stuff for us. Go to File/New project/ when asked for the kind of project, pick console application.

Tell it you want a C++ project. It will then ask you for a project title, folder, etc. For them use the name of the problem and the location in your Greed workspace. In following image, my Greed workspace is /home/vx/topcoder. We want the project file in the same folder as the source code and sample...

It will then ask you for what compiler to run. You should have already set up the correct compiler: (Hint: You'd like GCC 4.8.1 (Mingw in windows) to simulate TopCoder's server the best). If you ask me, you probably don't need a release configuration, as you only want to test code before sending to topcoder, leave it as debug.

Now we have some issues... First, it unilaterally decided that you want the main file to be called main.cpp. We would like it to be the same file as greed generated. Let's change it to TBlocks.cpp. Right click main.cpp and select remove file. Now right click the Project name and select Add files and add the TBlocks.cpp file generated by greed.

Another thing, you'd probably like c++11 support (and I hope you are using gcc 4.8.1) so go to Project/Build options... And tell it to use c++0x.

Actually, there is a plethora of options you'd like to set. To mimic topcoder the best, you'd like "Optimize even more (-O2)" and also I recommend to add "-Wreturn-type -Wcomment -Wunused-variable -Wunused-parameter -Wno-sign-compare" (without quotes) to the other options section.

After this, running the source code by pressing F9 will work just fine. Code::blocks will run the project in the directory we wanted.

Of course, doing this for every single problem is too much trouble, so we'll now use Greed's power to automatize it.

A code::blocks project template

All about greed works using templates. What we'd like Greed to do is to create a project file automatically for each problem. Code::blocks project files are saved with cbp extension and are actually XML files. Let's save all work we put in Code::blocks (Make sure to save the project!) and open TBlocks.cbp:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
 <FileVersion major="1" minor="6" />
 <Project>
  <Option title="TBlocks" />
  <Option pch_mode="2" />
  <Option compiler="gcc" />
  <Build>
   <Target title="Debug">
    <Option output="bin/Debug/TBlocks" prefix_auto="1" extension_auto="1" />
    <Option object_output="obj/Debug/" />
    <Option type="1" />
    <Option compiler="gcc" />
    <Compiler>
     <Add option="-O2" />
     <Add option="-std=c++0x" />
     <Add option="-g" />
     <Add option="-Wreturn-type -Wcomment -Wunused-variable -Wunused-parameter -Wno-sign-compare" />
    </Compiler>
   </Target>
  </Build>
  <Compiler>
   <Add option="-Wall" />
   <Add option="-fexceptions" />
  </Compiler>
  <Unit filename="TBlocks.cpp" />
  <Extensions>
   <code_completion />
   <debugger />
  </Extensions>
 </Project>
</CodeBlocks_project_file>

The rest is to create a Greed template to generate files like that. Let's first define the template in greed.conf. If you don't already have this file in your Greed workspace, create it.

greed {
    shared {
        templateDef {
            codeblocks {
                override = false
                outputFile = "${Problem.Name}.cbp"
                templateFile = "codeblocks.cbp.tmpl"
            }
        }
    }
}

That is the basic stuff you need to add a new template to greed. The template will be called codeblocks. By default the file won't be overrided if it already exists. The template file will be codeblocks.cbp, located in your workspace folder. The file it generates will be called just like the problem name and be put in the code root folder (same folder as source and sample). What we'd like for this file is to be exactly like the one above, except to replace TBLocks with whatever problem name we need:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
 <FileVersion major="1" minor="6" />
 <Project>
  <Option title="${Problem.Name}" />
  <Option pch_mode="2" />
  <Option compiler="gcc" />
  <Build>
   <Target title="Debug">
    <Option output="bin/Debug/${Problem.Name}" prefix_auto="1" extension_auto="1" />
    <Option object_output="obj/Debug/" />
    <Option type="1" />
    <Option compiler="gcc" />
    <Compiler>
     <Add option="-O2" />
     <Add option="-std=c++0x" />
     <Add option="-g" />
     <Add option="-Wreturn-type -Wcomment -Wunused-variable -Wunused-parameter -Wno-sign-compare" />
    </Compiler>
   </Target>
  </Build>
  <Compiler>
   <Add option="-Wall" />
   <Add option="-fexceptions" />
  </Compiler>
  <Unit filename="${Problem.Name}.cpp" />
  <Extensions>
   <code_completion />
   <debugger />
  </Extensions>
 </Project>
</CodeBlocks_project_file>

We would just like the template to be created whenever we open the problem. Since it is specific to c++ we will modify the c++ templates line.

greed {
    language {
        cpp {
             templates = [ filetest, source, testcase, problem-desc, codeblocks ]
        }
    }
}

The templates line is usually [ filetest, source, testcase, problem-desc ], it is the list of templates to create automatically. By adding codeblocks, we tell greed to create the codeblocks template. In greed reload the configuration, if everything went right, open some other problem, like the 400 points problem in the same TCO finals match.

It should say: Generating template [codeblocks] -> TCO 2013 Finals/PackingSquares.cbp or something like that, depending on the folder.

Now open the newly-created PackingSquares.cbp in Code::blocks, it should have everything set up, including the new source file.

After generation hook

How about that, instead of just creating the project file and needing us to open it manually, Greed also ordered Code::blocks to open it when we open the problem? All is possible.

To the part where we added the codeblocks template, add this:

            codeblocks {
                override = false
                outputFile = "${Problem.Name}.cbp"
                templateFile = "codeblocks.cbp.tmpl"
          afterFileGen {
              execute = codeblocks
              arguments = ["${GeneratedFilePath}"]
          }
            }

Now whenever the project file is regenerated (You may need to tell greed to regenerate code for problems you already opened) code::blocks will be opened...

The arguments part tells codeblocks what file to open. GeneratedFilePath is a special variable that returns the whole path to the file generated by the template.

Ok , we have a problem, if code::blocks was closed before opening the problem/regenerating the code then code::blocks will close immediately after opening. This is because Greed will run the new process without creating a thread. I will ask for an option to fix this in greed, but for now, we have a couple of workarounds, the first is to have code::blocks open while running the arena. The other is to create a script to run code::blocks in another thread for us. In *n*x* operating systems, save the following as threadcodeblocks.sh in greed's workspace folder, remember to set it as executable in permissions:

#!/bin/bash
codeblocks '$1' &

Change the execute = codeblocks line to execute = /path/to/greed/workspace/folder/threadcodeblocks.sh.

And done!

Comments / etc?

I hope it was useful. I think that every decent IDE out there saves project files as XML, there might be variations, but it is usually a text file, I hope.

Thursday, December 12, 2013

New version of my Greed tester and template

Shortly after I discovered the Greed topcoder plugin, I spent some time customizing its templates and later did some really cool stuff by making a generic tester. It has been working great so far.

During the weekend a discussion erupted at the Greed github about making Greed support running test cases in different thread/process the main reason people like this feature is because if you make code that depends on global variables' values and requires them to be initialized with 00 bytes, then running all test cases as part of the same process causes errors. I never really cared much about this, because I wouldn't ever use globals like that :/. But during the weekend I figured I had good reason to use this sort of feature:

  • Sometimes I need to test some other people's code locally and they have the sort of bad taste about global usage that I described. E.g, during the weekend I had to reverse engineer the solution rng_58 wrote for the SRM 599 Hard problem.
  • Most importantly, there is a much better reason to run in multiple processes: Runtime errors. C++ poor exception handling makes it so in my old version of tester, a single failed assert, a segfault or an exception would stop the execution of the whole thing. If the exception happened in just test case 1, it would still halt the execution of all test cases.

So that is when I started to experiment. The first thing I did was make Greed 2.0's default test template get this feature. I did some hacky stuff: Basically, the c++ program calls itself over and over again for each argument. But it works.

For my so-called "dualcolor" templates though, the requirements were higher because there is a lot more things to care about when printing results. The report at the end needs to know exactly what happened during the execution of test cases. Another issue is that I wouldn't be able to have access to the command line arguments in the tester file, unless I modified the tester call syntax (which would break old source files generated by old version of the template). So I had to do something else.

The eventual decision was to use fork and wait. fork() works great because it makes a copy of the current process. Wait is needed to wait for the process to end. The one problem about this is that it effectively makes the feature unable to work under windows (unless you use cygwin, I think). I make these templates for myself mostly and I don'tt have time to port to winapi. If you use windows and wanted this feature in my template I guess it sucks it when someone's software doesn't work fully on your OS of choice, eh?. Of course, maybe windows users still want the other cool features like the output colors and the easy-to-modify test cases, so when running in windows the whole thing is disabled. Metaprogramming to the rescue.

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32) && !defined(__CYGWIN__)
    #define DISABLE_THREADS
#endif
#ifndef DISABLE_THREADS
    #define DO_THREADS
#endif
#ifdef DO_THREADS
   #include <unistd.h>
   #include <sys/wait.h>
   #include <sys/types.h>
#endif

The other negative side is that communicating with child process was sort of too complicated for me to implement without using an external file. So the tester now needs an external file to work. Currently it is located in /tmp/

Maybe some *n*x users have trouble getting this to work. Or maybe it is failing for some reason or making testing a specific problem difficult. Hence why if the DISABLE_THREADS thing is defined before including the tester.cpp file, the feature can be disabled.

The result is great. It can catch the usual issues (aborted due to some std:: exception, division by zero, segfault). To be consistent with the python version, letter E is used to signify test cases with runtime errors. Here is a sample:

Keeping one line per test case in the report

Another feature that can be caught in the screenshot above is that the final results report in the bottom is now guaranteed to be one-line long. If the reported results is longer than that, it will be stripped. Of course, the line length can be configured in tester.cpp.

Return of the super compact mode

By popular (one person) demand. The mode that printed just and only the "final" report and nothing else is back. I don't like it because it doesn't work very well when you use printing for debugging. But I guess there are people who don't do that.

To choose output mode, find this line in template:

        return Tester::runTests<${ClassName}>(
            getTestCases<input, Tester::output<${Method.ReturnType}>>(), disabledTest, 
            ${Problem.Score}, ${CreateTime}, CASE_TIME_OUT, Tester::FULL_REPORT
        );

Change Tester::FULL_REPORT to one of these:

  • Tester::FULL_REPORT : Full , verbose output and report at the end.
  • Tester::NO_REPORT : Full , verbose output but the bottom report is a single line with less info.
  • Tester::ONLY_REPORT : Only the report and nothing more.

Get them

  • Test code template for greed, needs Greed 2.0 unless you tweak something small. testtemplate.cpp
  • Generic Tester (Place at .. folder relative to where source codes are generated): tester.cpp

The official Greed version 2.0 is probably going to include these templates and just need a small configuration line to use them. Greed git already includes the older version.

Saturday, November 16, 2013

Bragging about incoming Greed features part 2

Last time I mentioned that Greed Topcoder arena plugin is getting a 2.0 version that has plenty of nice features. Between that last post and today, many things happened. The first is that Greed 2.0 is now officially in beta state. So you can now get the jar in the releases page. If you used Greed 1.5, the configuration has really changed, it might actually be more productive to start configuration all over from the beginning and try to reuse your templates if they were too complicated. (There is only one breaking change in the template format, the ;zeroVal was changed with ;zerovalue, but the configuration file has really changed).

Also important: I committed a couple of cool things that will also be part of the new version. These changes are not in the beta jar, so you might have to compile the git branch yourself if you want to try them now. If you can wait, that's better.

Modulo detection

Counting problems in algo contests tend to ask you for the result modulo 1000000007, or modulo 1000000009 or some other large prime. This is because everyone hates bignums. Anyway, it does add a bit of an annoyance when solving these problems, you have to paste the number in your code, preferably as a constant. In TopCoder, they have the bad habit of using the absurd format that uses commas as separators , so the constant appears in the statement as 1,000,000,007. So you actually have to remove the commas. This is if you actually think of using copy paste, maybe you don't and just type the number manually, possibly typing the wrong number (like using 1000000009 instead of 1000000007 or missing a zero).

We deserve better. Now that greed has access to the problem statement, it occurred to me that it could totally try to detect this modulo. It looks for the phrase ":modulo (some number)" and then saves the number in a convenient spot. If there are multiple of them, it saves the last one that is mentioned, because that tends to be one of the last phrases in the statement. It probably won't work all the time, but most of the time it shall be of some help.

My template looks like this:

${<if Problem.Description.Modulo}
    static const int MOD = ${Problem.Description.Modulo}; 
${<end}

The result is:

    static const int MOD = 1000000007;

Or whatever number is parsed. This constant is only added if the Modulo was detected. You know, automatically.

The colorful templates with generic tester

I added tweaked versions of my current templates so that it is easy to use them in greed out of the box after just tweaking two configuration lines.

More info

Friday, November 08, 2013

Some great incoming topcoder-greed features

So Greed is a topcoder Arena plugin that is very customizable (And I mean, very customizable).

When I started using these plugins I took advantage of its github to provide patches and suggestions. This helped shivawu implement some wonderful features that will make Greed 2.0 a plugin with unprecedented power (I think).

Custom templates

In the current stable version, there are 3 templates: source, tester and unit tests (optional for Java and C#). The 2-3 templates are used by Greed to generate the source and unit test files. The templates use a language of their own that is very powerful. So powerful that implementing python support almost didn't need much modification to the plugin itself, just the creation of templates for python and an update to make the plugin use them.

Why stop there, though? The new idea is that you can, define custom templates. Any template for any kind of file in addition to the source and test ones. The plugin will use its configuration to read a template and put the generated contents in some location that depends on contest name and problem name. Why is this important? Well, it adds plenty of options that weren't there before. After some tweaking I was able to customize greed to generate ACM-style input and output files and a source code file that takes input and generates output ACM style.

This is the input file generated for FoxAndGo3:

6

3
o.o
.o.
o.o

3
...
.o.
...

5
xxxxx
xxoxx
xo.ox
xxoxx
xxxxx

5
.xox.
.o.ox
x.o.o
ox.ox
.ox..

5
o.o.o
.ox..
oxxxo
..x..
o.o.o

3
...
...
...

But I really didn't want these input/output files, I like my meta testers just fine. However, this feature is also helpful for other things. How about automatically creating a project XML file for your favorite IDE's ? Or a build file for whatever build system you have? Separating tester and source code. Whatever you need you can now do it.

Problem statement HTML

The first good use for the custom templates is that, just by adding some info from the problem statement to the template engine. The plugin can now generate problem statement HTML files from a template. Because it is a template, there is plenty of flexibility in regards to the format of the problem statement. The default looks like this:

There are plenty of uses for saving the problem statements in files. If the internet goes down during the contest, you can pretty much still work in the problem - You can read the problem and the source code is in an external file.

After generation hooks

My favorite new feature is, however, the "After Gen Hook" as it makes everything work great now. You can tweak configuration so, whenever Greed finishes generating a file from a specific template, it runs a custom command. Whatever command you need.

In my case, I tweaked Greed to make it automatically open source code files in jEdit, and opens the problem statement in Firefox. Manually opening the generated source code files in jEdit was an annoying bottleneck.

How to get the features

They are currently in a test branch and are still in development. But if you want to give them a try, just get the contents of the tmpl-seq branch from their github. The command to build a jar file from the new sourcecode is ./gradlew fatjar.

The new configuration options are not documented, so you will need to take a look to at the default.conf file in the source/main/resources folder and do some reverse engineering.

Sunday, October 06, 2013

c++ and python topcoder generic testers

A sequel to post: did I just spent all my Saturday customizing my Tester?. I have been improving the idea further. After adapting the ideas to python, it caused me to work harder in the c++ version.

Test case format

When I tried to adapt the ideas to python, I was able to have this useful format for test cases:

TEST_CASES = [
    ( [ ("---","---","---",) ], 0 ),
    ( [ ("-X--","---X","----","-X--",) ], 1 ),
    ( [ ("XXXX","---X","---X","---X",) ], 2 ),
    ( [ ("XX-XX--","-XX-XXX","X-XX--X","X--X-X-","XX-X-XX","-X-XX-X","-XX-XX-",) ], 3 ),
    #Your custom test goes here:
    #( [ ], None ),
]

This would be an example for SRM 593 div1 250: HexagonalBoard. It is much simpler than the odd template stuff that I barely managed to have in c++ and it is shorter.

It led me to try to work harder on the c++ version, maybe there really was a way to use {} format without having to type input {} and output {}... It turns out that once you are using constructors you can totally use them:

template<class I, class O> vector<pair<I,O>> getTestCases() { return {    
    { { {"---","---","---"} }, {0} },
    { { {"-X--","---X","----","-X--"} }, {1} },
    { { {"XXXX","---X","---X","---X"} }, {2} },
    { { {"XX-XX--","-XX-XXX","X-XX--X","X--X-X-","XX-X-XX","-X-XX-X","-XX-XX-"} }, {3} },
    // Your custom test goes here:
    { { {"XXXX","XXXX","XXXX","XXXX"} }, {3} },
    { { {"XX-","---","---"} }, {2} },
    { { {"XX","--"} }, {2} },
    { { {"-XX", "X-X", "XX-"} }, {2} },
    { { {"-XX","X-X","XX-"} }, {2} }
    { { {"XXX","XXX","XXX"} }, { } }
    //{ { {}}, {} },    
};}

You can see some custom examples I added today during the match and also while working on the problem for the editorial. An empty { } for the output means the output is unknown...

This works because we are calling constructors of an input and an output structs. The input struct has an implicit constructor to fill all the arguments of a problem. The output has two constructors, one that takes an output result, and one that takes no arguments. The reason {} syntax wasn't working for tuples, was that tuples apparently define only an explicit constructor? Either way once you switch to fixed structs it finally works.

This input format in c++ is quite useful. The compatibility with TopCoder's system tests format makes debugging during practice easier. Also it is easy to copy test cases you created and have stored in the file to the challenge window.

Making the problem-specific code as small as possible

The whole idea of the "meta-tester" is to have the code baggage that we need to automatically generate and include in the problem's file as small as possible. That's why I wanted to have most of the tester in a separate file that is not-specific to a single problem but works with any problem (It is also easier to edit the tester this way). Again, python made it way too easy. This is a sample file generated for python for the HexagonalBoard problem:

import math,string,itertools,fractions,heapq,collections,re,array,bisect
# SRM 593 - HexagonalBoard (250 points) by vexorian :

class HexagonalBoard:
 def minColors(self, board):
    return 0

# CUT begin
#-------------------------------------------------------------------------------
CASE_TIME_OUT = 2.00

TEST_CASES = [
    ( [ ("---","---","---",) ], 0 ),
    ( [ ("-X--","---X","----","-X--",) ], 1 ),
    ( [ ("XXXX","---X","---X","---X",) ], 2 ),
    ( [ ("XX-XX--","-XX-XXX","X-XX--X","X--X-X-","XX-X-XX","-X-XX-X","-XX-XX-",) ], 3 ),
    #Your custom test goes here:
    #( [ ], None ),
]

def isTestDisabled(i):
    return False

#-------------------------------------------------------------------------------
if __name__ == '__main__':
    import sys, tester
    tester.run_tests(
        HexagonalBoard, 'minColors', TEST_CASES, isTestDisabled, 
        1381033582, 250, CASE_TIME_OUT, True
    )
# CUT end

look at, basically the only part code that is not useful for the problem is the call to the tester.run_tests(). Everything else - The problem class that will be sent to topcoder, the TEST_CASES array that allows us to add test cases and the isTestDisabled() function that allows test cases to be disabled - Is very useful to have in the problem's code file.

How does run_tests work? First, it needs to receive the TEST_CASES list and the isTestDisabled function. But we can also send it the HexagonalBoard class. Python is quite dynamic, so it can even instantiate objects from a variable that determines what class. minColor is between quotes, it is the name of the method. After instantiating HexagonalBoard() it needs to call the method, we use a trick like:

getattr(instance, methodName)( arguments list)

to use the method name to call the method from an instance.

The input / arguments list we are supposed to send this method. Python stores them in a list. And no matter the list, we can uncompress it when sending this group of arguments to the method by using the * python operator:

getattr(instance, methodName)( *some_list)

Since the python code was getting so small, I tried to work more in the c++ one. The first candidate for cleaning was the output struct. It is a struct that holds the return type, a boolean to say that there is no return value and two constructors:

struct output {
    int value; bool u=false;
    
    output(int value) { this->value = value; }
    output() { u = true; }
};

We can actually make this thing a template. Being a template we need the code to exist in the generic tester instead of being specific to the problem:

template<typename T> struct output {
    T value; bool u=false;
    
    output(T value) { this->value = value; }
    output() { u = true; }
};

The real code bloat came from the input struct though:

struct input {
    vector<string> board;
     
    int run(double & elapsed) {
        StringPath* instance = new StringPath();
        time_t s = clock();
        int r = instance->countBoards( this->board );
        elapsed = (double)(clock() - s) / CLOCKS_PER_SEC;
        delete instance;
        return r;
    }
 
    void print() {
        cout << "[" << Tester::pretty(board) "]";
    }
};

What complicates things in c++ is that the number of arguments the method needs might vary. I think it might be possible to do this all with a variable template, however, maybe the reason tuples use explicit constructors is because of a limitation in the variadic-ness? Also, it sounds very complicated to do it. So I looked for other ways to reduce the footprint.

The print() method exists because of the variable number of arguments. So the part of the generic tester that needs to print the arguments can't do it alone. However, there was too much code in the print() method. Also, it determined the format the arguments are printed instead of letting the generic tester do it. I managed to create a variadic template that prints any sequence of arguments of any type, following the tester's format:

/*==============================================================================
  Converts given argument into a string containing pretty-looking output
*/
string pretty(string s)
{
    return "\"" + s + "\"";
}
string pretty(double x)
{
    ostringstream s;
    s.precision(10);
    s << x;
    return s.str();
}
template <typename T> string pretty(T t) {
    ostringstream s;
    s << t;
    return s.str();
}
template <typename T> string pretty(vector<T> t)
{
    ostringstream s;
    s << "{";
    for (int i=0; i<t.size(); i++) {
        s << (i?",":"") << t[i];
    }
    s << "}";
    return s.str();
}

/*==============================================================================
  Prints a test case's argument list
  
  printArgs(a,b,c) ->  cout << "[" << pretty(a) <<","<< pretty(b) <<"," <<  pretty(c) <<"]"
*/
void printArgsCont() {}

template<typename T, typename... Args> void printArgsCont(T value, Args... args)
{
    cout << "," << pretty(value);
    printArgsCont(args...);
}

template<typename T, typename... Args> void printArgs(T value, Args... args)
{
    cout << "[" << pretty(value);
    printArgsCont(args...);
    cout << "]";
}

Variadic templates are just great life savers. Now the print() method in the output struct looks like this:

void print() { Tester::printArgs( /*list of comma-separated arguments*/ ) ; }

The larger code usage in input struct was the run method. It also implemented tons of things that should really belong to the tester code, like measuring time or constructing the problem class. Well, it turns out that since the constructor for the problem class has no arguments, the tester can instanciate the problem class (we would need it to be a template argument). The new run method can just take a pointer to the class instance. It just needs to call the method. It is also not necessary to measure time inside the run() method, the tester can measure the amount of time the run() method takes, the overhead would be minor.

struct input {
    /*variables that hold each of the arguments*/;

    int run( /*ProblemClass*/ * x) {
        return x->minColors( /* comma - separated arguments */ );
    }
    void print() { Tester::printArgs( /* comma - separated arguments */ ); }
};

Problem name

At one point the tester received the problem name both as a string and as a template argument. Was it possible to make it receive it just as a template argument? There is something called typeid(T).name() in c++. Unfortunately, it seems to return some random numbers before the class name in gcc. It turns out we can fix it...

/*==============================================================================
    Returns the name of a type in human-readable form. It likely only works 100%
    correctly with classes that don't belong to a namespace and is not very
    portable.
*/
template<typename T> string getTypeName()
{
    string s = typeid(T).name();
    int i= 0; 
    while ( (i < s.size()) && ('0' <= s[i] && s[i] <= '9') ) {
        i++;
    }
    return s.substr(i);
}

What if?

The issue with the input struct is that it has to store the arguments. What if an argument is called input? That would cause some compile errors. A fix is to call the struct _input, it is unlike TopCoder would name arguments starting with _. We can also just add _ to all the argument names. But a method that also reduces the amount of code is to name the arguments inside the input struct as just (p0, p1, p2, ...). Unfortunately, greed 1.5 didn't have an option to get the number / index of an argument. I actually had to do a pull request to add this . The next version of greed should have the feature, but you can also just get the latest source code from github and compile it. Or modify the test code template I'll attach soon so that it uses a _input struct

The result

This is how the c++ test code generated for HexagonalBoard looks like:

#include <bits/stdc++.h>
// SRM 593 - HexagonalBoard (250 points) by vexorian
using namespace std;

struct HexagonalBoard
{
    int minColors(vector<string> board)
    {
        return 0;
    }
};

// CUT begin
//------------------------------------------------------------------------------
const double CASE_TIME_OUT = 2.0;

bool disabledTest(int x)
{
    return 0 * x;
}
template<class I, class O> vector<pair<I,O>> getTestCases() { return {
    { { {"---","---","---"} }, {0} },
    { { {"-X--","---X","----","-X--"} }, {1} },
    { { {"XXXX","---X","---X","---X"} }, {2} },
    { { {"XX-XX--","-XX-XXX","X-XX--X","X--X-X-","XX-X-XX","-X-XX-X","-XX-XX-"} }, {3} },
    // Your custom test goes here:
    //{ { {}}, {} },
};}

//------------------------------------------------------------------------------
// Tester code:
    #include "../tester.cpp"
    struct input {
        vector<string> p0;

        int run(HexagonalBoard* x) {
            return x->minColors(p0);
        }
        void print() { Tester::printArgs(p0); }
    };
    
    int main() {
        return Tester::runTests<HexagonalBoard>(
            getTestCases<input, Tester::output<int>>(), disabledTest, 
            250, 1381061147, CASE_TIME_OUT, true
        );
    }
// CUT end

The extra code that is not solution and not test cases is very small now. I wonder if this is the smallest it can get. Probably not if it is possible to do the input with variadic templates.

Tweaks to the tester

While modifying the auto-generated codes, I also tweaked the tester. Remember the dilemma between compact and not compact code? I think the appeal of the compact code is as a report. This way things like output results kind of pollute the report. I turned the whole thing into a hybrid. First it runs each test case and the output shows everything including parameter lists and results and the test cases are separated by a big part. At the end though, a report is shown. The report has just the results and a debug mesage won't clip it. It looks like this:

(I also found out a perfect character and format to represent a disabled case (test 5 in the image is disabled).

By modifying the boolean value in the call to the tester, you can switch to the old format...

Get stuff

Saturday, September 21, 2013

Did I just spent all my saturday customizing my Tester?

A word of caution about the Greed plugin. It might enable certain obsessive aspects of your personality.

I was not entirely happy with my previous solution to the Tester problem. So I began customizing even more.

The more I used the previous version of my tester, the more annoyed I was at the select case syntax of c++. It is awful. The need for break really kills me. Also, the whole thing with marking the last test cases with 'm' was messy.

I decided the optimal solution would be to abuse initializer lists and tuples and make the part of the code that saves test cases something like this:

typedef tuple< tuple<int,int,string,string>, int > test;

vector<test> testCases = {
     {  { 2, 2, "ABC", "ADC" }, {2} },
     {  { 2, 2, "ABC", "ABD" }, {0} },
     {  { 3, 4, "ABCDDE", "ACCBDE" }, {1899302} },
     {  { 8, 8, "ZZZZZZZZZZZZZZZ", "ZABCDEFGHIJKLMZ" }, {120390576} },
    // Your custom  goes here:
    // {  { , , , },  {} },
};

This would be the test case section for the StringPath problem. This has many advantages over the previous thing. It is less verbose. Adding a test case is just creating a new line. In case a single line is confusing we can add some formatting. It is also exactly the way input is represented in TC's system tests.

In order to use tuples like this, I would have to heavily modify the template, including the part that does the testing. I would need to extract parts of the tuple through indexes. But Greed doesn't have a field that gives an index to a parameter in the function. So in fact I had to update the source code. The fork that has this feature is at github.

Some time after adding the feature to Greed, I learned some very sad news. My initial idea of doing that with tuples and initializer lists did not work. Tuples don't support initializer lists like that. Initializer lists are also supposed to be used for things that have the same type... Back to square one.

The constructor idea

Although tuples don't allow that usage of initializer lists, they do have constructors, and constructors do support a {} syntax. So the following is possible:

vector<test> testCases = {
     tuple< tuple<int,int,string,string>, int > { tuple<int,int,string,string> { 2, 2, "ABC", "ADC" }, 2 },
     tuple< tuple<int,int,string,string>, int > { tuple<int,int,string,string> { 2, 2, "ABC", "ABD" }, 0 },
     tuple< tuple<int,int,string,string>, int > { tuple<int,int,string,string> { 3, 4, "ABCDDE", "ACCBDE" }, 1899302 },
     tuple< tuple<int,int,string,string>, int > { tuple<int,int,string,string> { 8, 8, "ZZZZZZZZZZZZZZZ", "ZABCDEFGHIJKLMZ" }, 120390576 },
     // Your custom  goes here:
     //tuple< tuple<int,int,string,string>, int > { tuple<int,int,string,string> { , , ,  },  },
};

But that is awful, you might say, well, not so much if we use typedefs:

typedef tuple<int,int,string,string> input;
typedef tuple<int> output;
typedef tuple< input, output > test;

vector<test> testCases = {
     test { input { 2, 2, "ABC", "ADC" }, output{2} },
     test { input { 2, 2, "ABC", "ABD" }, output{0} },
     test { input { 3, 4, "ABCDDE", "ACCBDE" }, output{1899302} },
     test { input { 8, 8, "ZZZZZZZZZZZZZZZ", "ZABCDEFGHIJKLMZ" }, output{120390576} },
    // Your custom  goes here:
    //test {  input { , , , }, output {} },
};

That... actually seems cool, doesn't it? I think it is the closest I can get to the system test syntax in c++. In python though we can use tuples directly.

Unknown output

A new issue was that this doesn't allow you to mark a test as not having a known required output. Sometimes you add custom tests just to test for timeout or to learn the solution and you have no idea what the correct solution actually is. Then I thought, well if you are going to use constructor syntax... we might as well just create a struct...

typedef tuple<int,int,string,string> input;
struct output
{
    int value; //the value
    bool u;    //false if the output is known, else we ignore the value.
};
output unknown{ 0, true };
typedef tuple< input, output > test;

vector<test> testCases = {
     test { input { 2, 2, "ABC", "ADC" }, output{2} },
     test { input { 2, 2, "ABC", "ABD" }, output{0} },
     test { input { 3, 4, "ABCDDE", "ACCBDE" }, output{1899302} },
     test { input { 8, 8, "ZZZZZZZZZZZZZZZ", "ZABCDEFGHIJKLMZ" }, output{120390576} },
     
     // A test with an unknown value:
     test { input { 5, 4, "ZZZZZZZZ", "ZAAAABXZ" }, unknown },
     
     // Your custom  goes here:
     //test {  input { , , , }, output {} },
};

Initializing simple classes with the {} syntax tends to be a life saver. output{6} creates an output object that has value 6 and u = false. The unknown variable contains an output object that has u = true. So that the tester (the part that does the grading) can know the output doesn't exist.

Compact layout

Everybody seems to like compact layout for the output of the tester. So I wanted to give it a try. Because of colors, I can actually make the smallest output ever. It looks like this:

Certainly smaller than it was before:

However, I am undecided, so I made this an optional thing. Determined by the value of a boolean constant. I can actually change the constant whenever I want. So maybe I have the compact layout until I really need debugging power in which I enable the full-info layout.

Actually, after a while of using the compact layout, it seems to me that information is more important than the coolness. I remember so many times in which my solution always returns a number that is exactly the intended result plus 1. It is useful to see the intended result and the actual result. It is also useful to see the parameters. Also, the compact layout loses its charm when you start putting tons of debugging messages in your solution.

Clean code

An issue with a full-featured template is that it is generating tons and tons of code. But you are supposed to use the file to code a solution. The code creates visual bloat that is a distraction.

The vector that initializes test cases was at the top, but it still required many things to be declared before it. Things that are distractful. Optimally, the test cases should be as above as possible. Just bellow the solution code. But how?

How do you use the input tuple or the output struct before declaring them? Turns out the only way I found was to use a template...

#include <bits/stdc++.h>
using namespace std;

struct StringPath
{
    int countBoards(int n, int m, string A, string B)
    {
        return 0;
    }
};

// CUT begin
//------------------------------------------------------------------------------
const double CASE_TIME_OUT = 2.0;
const bool   COMPACT_MODE  = false;

template<class test, class input, class output>
vector<test> getTestCases() {

    return {
        test { input { 2, 2, "ABC", "ADC" }, output{2} },
        test { input { 2, 2, "ABC", "ABD" }, output{0} },
        test { input { 3, 4, "ABCDDE", "ACCBDE" }, output{1899302} },
        test { input { 8, 8, "ZZZZZZZZZZZZZZZ", "ZABCDEFGHIJKLMZ" }, output{120390576} },
        // Your custom test goes here:
        //test { input { , , ,  }, output {} },
    };
// output{} = unknown result.
}
bool disabledTest(int x)
{
    return x < 0;
}

// Dragons be below this line:

That is how the file generated for StringPath looks like, just before the part that has a lot of code. Very messy code. Possibly without line breaks so it doesn't take space.

This brought me a new problem. The unknown variable was no longer usable that easily. I eventually settled to making the output struct have explicit constructors: (value) constructs the output with a value . Constructor with no arguments: () creates an unknown output. So if we want a known value we use output{2}, and if we do not know the value, we use output{} with nothing between the braces.

That fix added yet more code to a bunch of code that was already quite bloated.

A meta-tester!

BEEHOLD! Most of the operations the tester performs were the same everywhere (for all problems). Most of the functions were the same everywhere . A good start would be to move all the library and configuration functions like a function called pretty that prints any function argument or return with added "" if there is a string somewhere. Or the thing that compares floating point variables using TopCoder rules. If we put all these library functions into an external file that is shared by all solutions to all problems that are generated by my greed template. This saves a few space.

The real deal is though, to make an abstraction for the tester. Most of what the tester does is the same for all problems: Run each of the n tests. Decorate the output, call solution for each test, show solution results. Only few things vary, the actual types and number of the arguments. The solution class and method. The return type. The problem class name, the time when you opened the problem and the vector of tests.

The vector of tests is already a vector of pairs of tuples and an output struct. What if we made a template main function for the tester that took the test cases vector, the types of the method and everything else and just did the repetitive things?

The first speed bump was that input was represented by a tuple. Processing tuples requires variadic templates and it would have been very messy to, for example, print the arguments, or call the problem class with individual arguments.

This was the moment where I figure out. Maybe OOP is the solution. I really, really, hate OOP. But I was already using an output object. An input object was not that much different. And it would be very useful. The input object stores the parameters of a single test case, but it also has a method to perform the actual test, return the result and measure the execution time. Another useful method is the one to print the argument list.

And the files generated for a single TopCoder problem now look like this:

#include <bits/stdc++.h>
using namespace std;

struct StringPath
{
    int countBoards(int n, int m, string A, string B)
    {
        return 0;
    }
};

// CUT begin
//------------------------------------------------------------------------------
const double CASE_TIME_OUT = 2.0;
const bool   COMPACT_MODE  = false;

template<class test, class input, class output>
vector<test> getTestCases() {

    return {
        test { input { 2, 2, "ABC", "ADC" }, output{2} },
        test { input { 2, 2, "ABC", "ABD" }, output{0} },
        test { input { 3, 4, "ABCDDE", "ACCBDE" }, output{1899302} },
        test { input { 8, 8, "ZZZZZZZZZZZZZZZ", "ZABCDEFGHIJKLMZ" }, output{120390576} },
        // Your custom test goes here:
        //test { input { , , ,  }, output {} },
    };
// output{} = unknown result.
}
bool disabledTest(int x)
{
    return x < 0;
}

//------------------------------------------------------------------------------
// Tester code:
    #include "../tester.cpp"
    struct input
    {
        int n; int m; string A; string B;
        
        int run(double & elapsed) {
            StringPath* instance = new StringPath();
            time_t s = clock();
            int r = instance->countBoards( this->n,this->m,this->A,this->B );
            elapsed = (double)(clock() - s) / CLOCKS_PER_SEC;
            delete instance;
            return r;
        }
    
        void print() { 
            cout << "[" << Tester::pretty(n) << ","<< Tester::pretty(m) << ","<< Tester::pretty(A) << ","<< Tester::pretty(B)  << "]";
        }
    };
    struct output {
        int value; bool u=false;
        
        output(int value) { this->value = value; }
        output() { u = true; }
    };
    
    int main() {
        Tester::runTests(
            getTestCases<pair<input,output>,input, output>(), disabledTest, 
            "StringPath", 900, 1379806426,
            CASE_TIME_OUT, COMPACT_MODE
        );
        return 0;
    }
// CUT end

Note how the part that says Tester code just contains the input / output structs and a main method that calls a runTests function that happens to be a template function. It takes basically everything as arguments, including the test cases, the problem score, the function that determines if a test case is disabled, the configuration constants...

This ../tester.cpp file is the same for all topcoder problems and it works nicely. The tester code in the problem file is very short and nice and takes 33 lines. The actual code in tester.cpp is 168 lines long.

The other benefit is that I can modify the tester.cpp without worrying about Greed't template systax. I can add new features to the tester like multi threading or running in a single thread.

I do wish I could get rid of the input and output structs...

This post is just intended to show once more the power of Greed. Here is the template that generates the files for any TC problem:

const double CASE_TIME_OUT = 2.0;
const bool   COMPACT_MODE  = false;

template<class test, class input, class output>
vector<test> getTestCases() {

    return {
${<foreach Examples e}
        test { input { ${foreach e.Input in , }${if in.Param.Type.Array}{${foreach in.ValueList v ,}${v}${end}}${else}${in.Value}${end}${end} }, output{${if Method.ReturnType.Array}{ ${foreach e.Output.ValueList v ,}${v}${end}}${else}${e.Output}${end}} },
${<end}
        // Your custom test goes here:
        //test { input { ${foreach Method.Params p , }${if p.Type.Array}{}${end}${end} }, output {} },
    };
// output{} = unknown result.
}
bool disabledTest(int x)
{
    return x < 0;
}

//------------------------------------------------------------------------------
// Tester code:
    #include "../tester.cpp"
    struct input
    {
        ${foreach Method.Params p  }${p.Type} ${p.Name};${end}
        
        ${Method.ReturnType} run(double & elapsed) {
            ${ClassName}* instance = new ${ClassName}();
            time_t s = clock();
            ${Method.ReturnType} r = instance->${Method.Name}( ${foreach Method.Params p ,}this->${p.Name}${end} );
            elapsed = (double)(clock() - s) / CLOCKS_PER_SEC;
            delete instance;
            return r;
        }
    
        void print() { 
            cout << "[" ${<foreach Method.Params p << ","}<< Tester::pretty(${p.Name}) ${<end} << "]";
        }
    };
    struct output {
        ${Method.ReturnType} value; bool u=false;
        
        output(${Method.ReturnType} value) { this->value = value; }
        output() { u = true; }
    };
    
    int main() {
        Tester::runTests(
            getTestCases<pair<input,output>,input, output>(), disabledTest, 
            "${Problem.Name}", ${Problem.Score}, ${CreateTime},
            CASE_TIME_OUT, COMPACT_MODE
        );
        return 0;
    }