Skip to content

Instantly share code, notes, and snippets.

@ramntry
Created July 2, 2014 13:40
Show Gist options
  • Save ramntry/b879a70ed33486ecf146 to your computer and use it in GitHub Desktop.
Save ramntry/b879a70ed33486ecf146 to your computer and use it in GitHub Desktop.
cf parser
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cctype>
#include <functional>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <numeric>
#include <limits>
#include <vector>
#include <string>
#include <deque>
#include <set>
#include <map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define DEFINE_MIN_MAX_CONSTANTS(TYPE) \
static int const TYPE##_max = numeric_limits<TYPE>::max(); \
static int const TYPE##_min = numeric_limits<TYPE>::min()
DEFINE_MIN_MAX_CONSTANTS(int);
DEFINE_MIN_MAX_CONSTANTS(ll);
DEFINE_MIN_MAX_CONSTANTS(ull);
DEFINE_MIN_MAX_CONSTANTS(double);
int main() {
return 0;
}
#!/usr/bin/python
# Python 2->3 libraries that were renamed.
try:
from urllib2 import urlopen
except:
from urllib.request import urlopen
try:
from HTMLParser import HTMLParser
except:
from html.parser import HTMLParser
# Other libraries.
from sys import argv
from subprocess import call
from functools import partial, wraps
import re
# User modifiable constants:
TEMPLATE='main.cpp'
COMPILE_CMD='g++-4.7 -g -std=c++03 -Wall -lm'
SAMPLE_INPUT='input'
SAMPLE_OUTPUT='right'
MY_OUTPUT='output'
# Do not modify these!
VERSION='CodeForces Parser v1.3'
RED_F='\033[31m'
GREEN_F='\033[32m'
BOLD='\033[1m'
NORM='\033[0m'
TIME_CMD='`which time` -o time.out -f "(%es)"'
TIME_AP='`cat time.out`'
class CodeforcesProblemParser(HTMLParser):
def __init__(self, folder):
HTMLParser.__init__(self)
self.folder = folder
self.num_tests = 0
self.testcase = None
self.start_copy = False
self.add = ''
def handle_starttag(self, tag, attrs):
if tag == 'div':
if attrs == [('class', 'input')]:
self.num_tests += 1
self.testcase = open(
'%s/%s%d' % (self.folder, SAMPLE_INPUT, self.num_tests), 'w')
elif attrs == [('class', 'output')]:
self.testcase = open(
'%s/%s%d' % (self.folder, SAMPLE_OUTPUT, self.num_tests), 'w')
elif tag == 'pre':
if self.testcase != None:
self.start_copy = True
def handle_endtag(self, tag):
if tag == 'br':
if self.start_copy:
self.testcase.write('\n')
if tag == 'pre':
if self.start_copy:
self.testcase.close()
self.testcase = None
self.start_copy = False
def handle_entityref(self, name):
if self.start_copy:
self.add += self.unescape(('&%s;' % name))
def handle_data(self, data):
if self.start_copy:
self.testcase.write(self.add+data)
self.add = ''
class CodeforcesContestParser(HTMLParser):
def __init__(self, contest):
HTMLParser.__init__(self)
self.contest = contest
self.start_contest = False
self.start_problem = False
self.toggle = False
self.name = ''
self.problems = []
self.problem_names = []
def handle_starttag(self, tag, attrs):
if tag == 'a':
if self.name == '' and attrs == [('style', 'color: black'), ('href', '/contest/%s' % (self.contest))]:
self.start_contest = True
else:
regexp = re.compile(r'[.]*/contest/%s/problem/[A-Z]' % self.contest)
string = str(attrs[0])
search = regexp.search(string)
if search is not None:
if self.toggle:
self.toggle = False
self.start_problem = True
self.problems.append(search.group(0).split('/')[-1])
else:
self.toggle = True
def handle_endtag(self, tag):
if tag == 'a' and self.start_contest:
self.start_contest = False
elif self.start_problem:
self.start_problem = False
def handle_data(self, data):
if self.start_contest:
self.name = data
elif self.start_problem:
self.problem_names.append(data)
def parse_problem(folder, contest, problem):
url = 'http://codeforces.com/contest/%s/problem/%s' % (contest, problem)
html = urlopen(url).read()
parser = CodeforcesProblemParser(folder)
parser.feed(html.decode('utf-8'))
return parser.num_tests
def parse_contest(contest):
url = 'http://codeforces.com/contest/%s' % (contest)
html = urlopen(url).read()
parser = CodeforcesContestParser(contest)
parser.feed(html.decode('utf-8'))
return parser
def generate_test_script(folder, num_tests, problem):
with open(folder + 'test.sh', 'w') as test:
test.write(
('#!/bin/bash\n'
'if ! '+COMPILE_CMD+' {0}.cpp; then\n'
' exit\n'
'fi\n'
'FAILED=no\n'
'INPUT_NAME='+SAMPLE_INPUT+'\n'
'OUTPUT_NAME='+SAMPLE_OUTPUT+'\n'
'MY_NAME='+MY_OUTPUT+'\n').format(problem))
test.write(
'for test_file in $INPUT_NAME*\n'
'do\n'
' i=$((${{#INPUT_NAME}}))\n'
' test_case=${{test_file:$i}}\n'
' rm -f -R $MY_NAME*\n'
' if ! {5} ./a.out < $INPUT_NAME$test_case > $MY_NAME$test_case; then\n'
' FAILED=yes\n'
' echo {1}{4}Sample test \#$test_case: Runtime Error{2} {6}\n'
' echo ========================================\n'
' echo Sample Input \#$test_case\n'
' cat $INPUT_NAME$test_case\n'
' else\n'
' if diff --brief $MY_NAME$test_case $OUTPUT_NAME$test_case; then\n'
' echo {1}{3}Sample test \#$test_case: Accepted{2} {6}\n'
' else\n'
' FAILED=yes\n'
' echo {1}{4}Sample test \#$test_case: Wrong Answer{2} {6}\n'
' echo ========================================\n'
' echo Sample Input \#$test_case\n'
' cat $INPUT_NAME$test_case\n'
' echo ========================================\n'
' echo Sample Output \#$test_case\n'
' cat $OUTPUT_NAME$test_case\n'
' echo ========================================\n'
' echo My Output \#$test_case\n'
' cat $MY_NAME$test_case\n'
' echo ========================================\n'
' fi\n'
' fi\n'
'done\n'
'if [ "$FAILED" == "no" ]; then\n'
' cat {7}.cpp | xclip -selection c\n'
'fi\n'
.format(num_tests, BOLD, NORM, GREEN_F, RED_F, TIME_CMD, TIME_AP, problem))
call(['chmod', '+x', folder + 'test.sh'])
def main():
print (VERSION)
if(len(argv) < 2):
print('USAGE: ./parse.py 379')
return
contest = argv[1]
print ('Parsing contest %s, please wait...' % contest)
content = parse_contest(contest)
print (BOLD+GREEN_F+'*** Round name: '+content.name+' ***'+NORM)
print ('Found %d problems!' % (len(content.problems)))
for index, problem in enumerate(content.problems):
print ('Downloading Problem %s: %s...' % (problem, content.problem_names[index]))
folder = '%s/%s/' % (contest, problem)
call(['mkdir', '-p', folder])
call(['cp', '-n', TEMPLATE, '%s/%s/%s.cpp' % (contest, problem, problem)])
num_tests = parse_problem(folder, contest, problem)
print('%d sample test(s) found.' % num_tests)
generate_test_script(folder, num_tests, problem)
print ('========================================')
print ('Use ./test.sh to run sample tests in each directory.')
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment