Codeforces用自動チェッカー

Codeforcesという新進気鋭のプログラミングコンテストがあるらしいので参加してみることにした。Practiceをやってみたところ、ICPCとほぼ同じ形式だった。入出力を自分でコピペするのが面倒だったので自動化してみた。ぶっちゃけ前に作ったPKU用の自動チェックスクリプトとほとんど同じ。TLEとかMLEとか対応していないので、そのうち対応するかもしれない。

#!/usr/bin/python
import os
import re
import subprocess
import sys
import urllib

def generateInputFileName(contestId, problemId, index):
    return contestId + problemId + '.' + str(index) + '.in.txt'

def generateOutputFileName(contestId, problemId, index):
    return contestId + problemId + '.' + str(index) + '.out.txt'

def format_pre(s):
    s = s.replace('<br />', '\n')
    if not s.endswith('\n'):
        s += '\n'
    return s

def download(contestId, problemId):
    url = 'http://codeforces.com/contest/' + contestId + '/problem/' + problemId
    html = urllib.urlopen(url).read()
    p = re.compile('<pre class="content">(.+?)</pre>', re.M | re.S)
    result = p.findall(html)
    n = len(result) / 2;
    for index in range(n):
        inputFileName = generateInputFileName(contestId, problemId, index)
        outputFileName = generateOutputFileName(contestId, problemId, index)
        open(inputFileName, 'w').write(format_pre(result[index * 2 + 0]))
        open(outputFileName, 'w').write(format_pre(result[index * 2 + 1]))
    return True

def compile(id):
    return subprocess.call(['g++', '-O2', problemId + '.cpp']) == 0

contestId = sys.argv[1]
problemId = sys.argv[2]

print('compiling...')
if not compile(problemId):
    print('CompileError')
    exit(-1)

if not os.path.exists(generateInputFileName(contestId, problemId, 0)) or not os.path.exists(generateOutputFileName(contestId, problemId, 0)):
    print('downloading...')
    download(contestId, problemId)

for index in range(100):
    inputFilePath = generateInputFileName(contestId, problemId, index)
    outputFilePath = generateOutputFileName(contestId, problemId, index)
    if not os.path.exists(inputFilePath):
        break
    print('TestCase ' + str(index) + ' ' + inputFilePath + ' ' + outputFilePath)
    p = subprocess.Popen(['./a.exe'], stdin=open(inputFilePath, 'r'), stdout=open('out.txt', 'w'))
    if p.wait() != 0:
        print('RuntimeError?')
        exit(-1)
    if os.path.exists(outputFilePath):
        if subprocess.call(['diff', outputFilePath, 'out.txt', '-wy', '-W', '79']) != 0:
            print('WrongAnswer')
            exit(-1)
    else:
        for line in open(outputFilePath):
            print(line)

print('OK')

追記(2010/03/12 19:22)

改行の処理を間違えていたので修正

追記(2010/05/06 22:56)

ファイル末尾の改行の処理を間違えていたので修正

追記(2010/05/07 01:10)

ファイル末尾の改行の処理を間違えていたので修正