gettc 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Rakefile +41 -0
- data/bin/gettc +63 -0
- data/core/lib/topcoder.rb +3 -0
- data/core/lib/topcoder/download.rb +89 -0
- data/core/lib/topcoder/generate.rb +131 -0
- data/core/lib/topcoder/parse.rb +231 -0
- data/core/lib/topcoder/print.rb +56 -0
- data/core/lib/topcoder/problem.rb +33 -0
- data/core/lib/topcoder/signature.rb +55 -0
- data/core/lib/topcoder/types.rb +62 -0
- data/core/test/topcoder/download_test.rb +29 -0
- data/core/test/topcoder/generate_test.rb +31 -0
- data/core/test/topcoder/parse_test.rb +104 -0
- data/core/test/topcoder/signature_test.rb +52 -0
- data/core/test/topcoder/types_test.rb +24 -0
- data/dist/config.yml +2 -0
- data/dist/include/cpp/engine.rb +90 -0
- data/dist/include/cpp/topcoder +212 -0
- data/dist/include/haskell/TopCoder.hs +82 -0
- data/dist/include/haskell/engine.rb +122 -0
- data/dist/include/java/TopCoder.jar +0 -0
- data/dist/include/java/engine.rb +207 -0
- data/dist/template/bin/runner.sh +113 -0
- data/dist/template/data/demo/{examples_d} +0 -0
- data/dist/template/data/sys/{systests_d} +0 -0
- data/dist/template/prob/images/{images_d} +0 -0
- data/dist/template/prob/{name}.html +8 -0
- data/dist/template/prob/{name}.md +1 -0
- data/dist/template/solve/cpp/Makefile +30 -0
- data/dist/template/solve/cpp/{name}.cpp +11 -0
- data/dist/template/solve/cpp/{name}Runner.cpp +26 -0
- data/dist/template/solve/cpp/{name}Test.cpp +8 -0
- data/dist/template/solve/haskell/Makefile +30 -0
- data/dist/template/solve/haskell/{name}.hs +7 -0
- data/dist/template/solve/haskell/{name}Runner.hs +27 -0
- data/dist/template/solve/haskell/{name}Test.hs +10 -0
- data/dist/template/solve/java/build.xml +78 -0
- data/dist/template/solve/java/{name}.java +9 -0
- data/dist/template/solve/java/{name}Runner.java +32 -0
- data/dist/template/solve/java/{name}Test.java +8 -0
- data/dist/template/util/check/Makefile +5 -0
- data/dist/template/util/check/check.cpp +26 -0
- metadata +121 -0
data/dist/config.yml
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'topcoder/types'
|
2
|
+
|
3
|
+
module TopCoder
|
4
|
+
class Type
|
5
|
+
def to_cpp
|
6
|
+
if self == TInt then
|
7
|
+
return 'int'
|
8
|
+
elsif self == TLong then
|
9
|
+
return 'int64'
|
10
|
+
elsif self == TFloat then
|
11
|
+
return 'float'
|
12
|
+
elsif self == TDouble then
|
13
|
+
return 'double'
|
14
|
+
elsif self == TChar then
|
15
|
+
return 'char'
|
16
|
+
elsif self == TString then
|
17
|
+
return 'string'
|
18
|
+
elsif self == TBoolean then
|
19
|
+
return 'bool'
|
20
|
+
elsif is_a? TArray then
|
21
|
+
ret = 'vector<' << subtype.to_cpp
|
22
|
+
ret << ' ' if subtype.is_a? TArray
|
23
|
+
ret << '>'
|
24
|
+
return ret
|
25
|
+
else
|
26
|
+
return 'unknown'
|
27
|
+
end
|
28
|
+
end
|
29
|
+
def dumb_cpp
|
30
|
+
if self == TInt then
|
31
|
+
return '0'
|
32
|
+
elsif self == TLong then
|
33
|
+
return '0'
|
34
|
+
elsif self == TFloat then
|
35
|
+
return '0'
|
36
|
+
elsif self == TDouble then
|
37
|
+
return '0'
|
38
|
+
elsif self == TChar then
|
39
|
+
return "'$'"
|
40
|
+
elsif self == TString then
|
41
|
+
return '"$"'
|
42
|
+
elsif self == TBoolean then
|
43
|
+
return 'true'
|
44
|
+
elsif is_a? TArray then
|
45
|
+
return "#{to_cpp}()"
|
46
|
+
else
|
47
|
+
return 'Nil'
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
class Signature
|
52
|
+
def to_cpp declaring = false
|
53
|
+
ret = type.to_cpp
|
54
|
+
ret << ' '
|
55
|
+
ret << 'const &' if declaring and type.obj?
|
56
|
+
ret << name
|
57
|
+
return ret
|
58
|
+
end
|
59
|
+
end
|
60
|
+
class CppEngine
|
61
|
+
attr_accessor :func, :vars
|
62
|
+
def initialize func, vars
|
63
|
+
@func = func
|
64
|
+
@vars = vars
|
65
|
+
end
|
66
|
+
def declare
|
67
|
+
ret = @func.to_cpp
|
68
|
+
ret << '('
|
69
|
+
indent = ' ' * ret.size
|
70
|
+
temp = @vars.map do |var| var.to_cpp true end
|
71
|
+
ret << temp.join(",\n#{indent}")
|
72
|
+
ret << ')'
|
73
|
+
return ret
|
74
|
+
end
|
75
|
+
def input
|
76
|
+
temp = @vars.map do |var|
|
77
|
+
x = var.to_cpp
|
78
|
+
x << '; read(ifs, '
|
79
|
+
x << var.name
|
80
|
+
x << ');'
|
81
|
+
end
|
82
|
+
return temp.join " next(ifs);\n"
|
83
|
+
end
|
84
|
+
def output
|
85
|
+
ret = 'show(ofs, ' << @func.name << '('
|
86
|
+
temp = @vars.map do |var| var.name end
|
87
|
+
ret << temp.join(', ') << '));'
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
#ifndef GETTC_TOPCODER_H
|
2
|
+
#define GETTC_TOPCODER_H
|
3
|
+
|
4
|
+
#include <algorithm>
|
5
|
+
#include <exception>
|
6
|
+
#include <string>
|
7
|
+
#include <vector>
|
8
|
+
#include <iostream>
|
9
|
+
#include <sstream>
|
10
|
+
#include <cmath>
|
11
|
+
#include <cctype>
|
12
|
+
|
13
|
+
typedef unsigned int uint;
|
14
|
+
typedef long long int64;
|
15
|
+
typedef unsigned long long uint64;
|
16
|
+
|
17
|
+
namespace TopCoder
|
18
|
+
{
|
19
|
+
const int _CHUNK_SIZE = 65536;
|
20
|
+
|
21
|
+
class ParseException: public std::exception {
|
22
|
+
private:
|
23
|
+
std::string message;
|
24
|
+
void buildMessage(std::string const &required, char actual,
|
25
|
+
std::string const &rest) {
|
26
|
+
std::ostringstream oss;
|
27
|
+
oss << required << " at: <" << rest << ">";
|
28
|
+
oss << " (got '" << actual << "')";
|
29
|
+
message = oss.str();
|
30
|
+
}
|
31
|
+
public:
|
32
|
+
ParseException() : message("ParseException occurred") {}
|
33
|
+
ParseException(std::string const &message) : message(message) {}
|
34
|
+
~ParseException() throw () {}
|
35
|
+
virtual const char* what() const throw() { return message.c_str(); }
|
36
|
+
|
37
|
+
ParseException(std::string const &required, char actual,
|
38
|
+
std::string const &rest) {
|
39
|
+
buildMessage(required, actual, rest);
|
40
|
+
}
|
41
|
+
ParseException(char expected, char actual,
|
42
|
+
std::string const &rest) {
|
43
|
+
std::ostringstream oss;
|
44
|
+
oss << "Expect '" << expected << "'";
|
45
|
+
buildMessage(oss.str(), actual, rest);
|
46
|
+
}
|
47
|
+
ParseException(std::string const &required, std::string const &rest) {
|
48
|
+
std::ostringstream oss;
|
49
|
+
oss << required << " at: <" << rest << ">";
|
50
|
+
message = oss.str();
|
51
|
+
}
|
52
|
+
ParseException(char expected) {
|
53
|
+
std::ostringstream oss;
|
54
|
+
oss << "Expect '" << expected << " before end of stream";
|
55
|
+
message = oss.str();
|
56
|
+
}
|
57
|
+
};
|
58
|
+
|
59
|
+
std::string _rest(std::istream &is) {
|
60
|
+
std::ostringstream oss;
|
61
|
+
char chunk[_CHUNK_SIZE];
|
62
|
+
while (is.good()) {
|
63
|
+
is.get(chunk, _CHUNK_SIZE);
|
64
|
+
oss << chunk;
|
65
|
+
}
|
66
|
+
return oss.str();
|
67
|
+
}
|
68
|
+
void _spaces(std::istream &is) {
|
69
|
+
while (is.good()) {
|
70
|
+
int i = is.peek();
|
71
|
+
if (isspace(i)) is.ignore(1);
|
72
|
+
else break;
|
73
|
+
}
|
74
|
+
}
|
75
|
+
void _expect(std::istream &is, char expected) {
|
76
|
+
_spaces(is); char actual = is.peek();
|
77
|
+
if (expected != actual)
|
78
|
+
throw ParseException(expected, actual, _rest(is));
|
79
|
+
is.ignore(1);
|
80
|
+
}
|
81
|
+
void next(std::istream &is) {
|
82
|
+
_expect(is, ',');
|
83
|
+
}
|
84
|
+
|
85
|
+
void read(std::istream &is, int &i) { is >> i; }
|
86
|
+
void read(std::istream &is, int64 &l) { is >> l; }
|
87
|
+
void read(std::istream &is, float &f) { is >> f; }
|
88
|
+
void read(std::istream &is, double &d) { is >> d; }
|
89
|
+
void read(std::istream &is, char &c) {
|
90
|
+
_expect(is, '\'');
|
91
|
+
is.get(c);
|
92
|
+
if (c == '\'') c = 0;
|
93
|
+
else _expect(is, '\'');
|
94
|
+
}
|
95
|
+
void read(std::istream &is, std::string &s) {
|
96
|
+
_expect(is, '"');
|
97
|
+
std::ostringstream oss;
|
98
|
+
while (is.good()) {
|
99
|
+
char c; is.get(c);
|
100
|
+
if (c == '\\') {
|
101
|
+
char cc; is.get(cc);
|
102
|
+
oss << cc;
|
103
|
+
}
|
104
|
+
else if (c == '"') {
|
105
|
+
s = oss.str();
|
106
|
+
return;
|
107
|
+
}
|
108
|
+
else oss << c;
|
109
|
+
}
|
110
|
+
throw ParseException('"');
|
111
|
+
}
|
112
|
+
void read(std::istream &is, bool &b) {
|
113
|
+
_spaces(is);
|
114
|
+
std::ostringstream oss;
|
115
|
+
while (is.good()) {
|
116
|
+
int i = is.peek();
|
117
|
+
if (!isalpha(i)) {
|
118
|
+
break;
|
119
|
+
}
|
120
|
+
oss.put(i);
|
121
|
+
is.ignore(1);
|
122
|
+
}
|
123
|
+
std::string s = oss.str();
|
124
|
+
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
|
125
|
+
if (s == "true") {
|
126
|
+
b = true;
|
127
|
+
} else if (s == "false") {
|
128
|
+
b = false;
|
129
|
+
} else {
|
130
|
+
throw ParseException("Expect a boolean value (true or false)", _rest(is));
|
131
|
+
}
|
132
|
+
}
|
133
|
+
template <typename T>
|
134
|
+
void read(std::istream &is, std::vector<T> &v) {
|
135
|
+
v.clear();
|
136
|
+
_expect(is, '[');
|
137
|
+
_spaces(is);
|
138
|
+
int i = is.peek();
|
139
|
+
if (i == ']') {
|
140
|
+
is.ignore(1);
|
141
|
+
return;
|
142
|
+
}
|
143
|
+
while (is.good()) {
|
144
|
+
T e; read(is, e); v.push_back(e);
|
145
|
+
_spaces(is); char c; is.get(c);
|
146
|
+
if (c == ']') return;
|
147
|
+
if (c != ',')
|
148
|
+
throw ParseException("Expect ',' or ']'", c, _rest(is));
|
149
|
+
}
|
150
|
+
throw ParseException(']');
|
151
|
+
}
|
152
|
+
|
153
|
+
void show(std::ostream &os, int i) { os << i; }
|
154
|
+
void show(std::ostream &os, int64 l) { os << l; }
|
155
|
+
void show(std::ostream &os, float f) {
|
156
|
+
os.precision(8);
|
157
|
+
os << f;
|
158
|
+
}
|
159
|
+
void show(std::ostream &os, double d) {
|
160
|
+
os.precision(16);
|
161
|
+
os << d;
|
162
|
+
}
|
163
|
+
void show(std::ostream &os, char c) {
|
164
|
+
os << '\'' << c << '\'';
|
165
|
+
}
|
166
|
+
void show(std::ostream &os, std::string const &s) {
|
167
|
+
os << '"' << s << '"';
|
168
|
+
}
|
169
|
+
void show(std::ostream &os, bool b) {
|
170
|
+
os << (b ? "true" : "false");
|
171
|
+
}
|
172
|
+
template <typename T>
|
173
|
+
void show(std::ostream &os, std::vector<T> const &v) {
|
174
|
+
typedef typename std::vector<T>::const_iterator Iterator;
|
175
|
+
bool first = true;
|
176
|
+
os << '[';
|
177
|
+
for (Iterator it = v.begin(); it != v.end(); ++it) {
|
178
|
+
if (!first) os << ',';
|
179
|
+
show(os, *it);
|
180
|
+
first = false;
|
181
|
+
}
|
182
|
+
os << ']';
|
183
|
+
}
|
184
|
+
|
185
|
+
bool same(int i, int j) { return i == j; }
|
186
|
+
bool same(int64 i, int64 j) { return i == j; }
|
187
|
+
bool same(char i, char j) { return i == j; }
|
188
|
+
bool same(std::string const &x, std::string const &y) { return x == y; }
|
189
|
+
bool same(float x, float y) {
|
190
|
+
float p = x * (1.0 - 1e-5);
|
191
|
+
float q = x * (1.0 + 1e-5);
|
192
|
+
return y >= std::min(p, q) && y <= std::max(p, q);
|
193
|
+
}
|
194
|
+
bool same(double x, double y) {
|
195
|
+
double p = x * (1.0 - 1e-9);
|
196
|
+
double q = x * (1.0 + 1e-9);
|
197
|
+
return y >= std::min(p, q) && y <= std::max(p, q);
|
198
|
+
}
|
199
|
+
template <typename T>
|
200
|
+
bool same(std::vector<T> const &v1, std::vector<T> const &v2) {
|
201
|
+
typedef typename std::vector<T>::const_iterator Iterator;
|
202
|
+
Iterator i1 = v1.begin(),
|
203
|
+
i2 = v2.begin();
|
204
|
+
while (true) {
|
205
|
+
if (i1 == v1.end()) return i2 == v2.end();
|
206
|
+
if (i2 == v2.end()) return false;
|
207
|
+
if (!same(*i1++, *i2++)) return false;
|
208
|
+
}
|
209
|
+
}
|
210
|
+
}
|
211
|
+
|
212
|
+
#endif /* GETTC_TOPCODER_H */
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module TopCoder ( next
|
2
|
+
, parseChar
|
3
|
+
, parseString
|
4
|
+
, parseBool
|
5
|
+
, parseInt
|
6
|
+
, parseLong
|
7
|
+
, parseFloat
|
8
|
+
, parseDouble
|
9
|
+
, parseList
|
10
|
+
, Parser
|
11
|
+
, parse
|
12
|
+
, spaces
|
13
|
+
) where
|
14
|
+
|
15
|
+
import Text.Parsec
|
16
|
+
import Text.Parsec.String (Parser)
|
17
|
+
import Text.Parsec.Token
|
18
|
+
import Data.Char
|
19
|
+
|
20
|
+
next :: Parser ()
|
21
|
+
next = do char ','
|
22
|
+
return ()
|
23
|
+
|
24
|
+
parseChar :: Parser Char
|
25
|
+
parseChar = do char '\''
|
26
|
+
ret <- anyChar
|
27
|
+
char '\''
|
28
|
+
return ret
|
29
|
+
|
30
|
+
parseString :: Parser String
|
31
|
+
parseString = do char '\"'
|
32
|
+
ret <- many1 (noneOf "\"")
|
33
|
+
char '\"'
|
34
|
+
return ret
|
35
|
+
|
36
|
+
parseBool :: Parser Bool
|
37
|
+
parseBool = do s <- many1 letter
|
38
|
+
return ((map toLower s) == "true")
|
39
|
+
|
40
|
+
parseInt :: Parser Int
|
41
|
+
parseInt = do char '-'
|
42
|
+
n <- parseInt
|
43
|
+
return (-n)
|
44
|
+
<|> do cs <- many1 digit
|
45
|
+
return (read cs)
|
46
|
+
|
47
|
+
parseLong :: Parser Integer
|
48
|
+
parseLong = do char '-'
|
49
|
+
n <- parseLong
|
50
|
+
return (-n)
|
51
|
+
<|> do cs <- many1 digit
|
52
|
+
return (read cs)
|
53
|
+
|
54
|
+
parseFloat :: Parser Float
|
55
|
+
parseFloat = do char '-'
|
56
|
+
x <- parseFloat
|
57
|
+
return (-x)
|
58
|
+
<|> do cs <- many1 (digit <|> char '.')
|
59
|
+
return (read cs)
|
60
|
+
|
61
|
+
parseDouble :: Parser Double
|
62
|
+
parseDouble = do char '-'
|
63
|
+
x <- parseDouble
|
64
|
+
return (-x)
|
65
|
+
<|> do cs <- many1 (digit <|> char '.')
|
66
|
+
return (read cs)
|
67
|
+
|
68
|
+
|
69
|
+
parseElems :: Read a => Parser a -> Parser [a]
|
70
|
+
parseElems f = do x <- f
|
71
|
+
spaces
|
72
|
+
do next
|
73
|
+
xs <- parseElems f
|
74
|
+
return (x:xs)
|
75
|
+
<|> return [x]
|
76
|
+
<|> return []
|
77
|
+
|
78
|
+
parseList :: Read a => Parser a -> Parser [a]
|
79
|
+
parseList f = do spaces >> char '['
|
80
|
+
xs <- parseElems (spaces >> f)
|
81
|
+
spaces >> char ']'
|
82
|
+
return xs
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'topcoder/types'
|
2
|
+
class String
|
3
|
+
def uncapitalize
|
4
|
+
return self[0, 1].downcase + self[1..-1]
|
5
|
+
end
|
6
|
+
end
|
7
|
+
module TopCoder
|
8
|
+
class Type
|
9
|
+
def to_haskell
|
10
|
+
if self == TInt then
|
11
|
+
return 'Int'
|
12
|
+
elsif self == TLong then
|
13
|
+
return 'Integer'
|
14
|
+
elsif self == TFloat then
|
15
|
+
return 'Float'
|
16
|
+
elsif self == TDouble then
|
17
|
+
return 'Double'
|
18
|
+
elsif self == TChar then
|
19
|
+
return 'Char'
|
20
|
+
elsif self == TString then
|
21
|
+
return 'String'
|
22
|
+
elsif self == TBoolean then
|
23
|
+
return 'Bool'
|
24
|
+
elsif is_a? TArray then
|
25
|
+
return '[' + subtype.to_haskell + ']'
|
26
|
+
else
|
27
|
+
return 'Unknown'
|
28
|
+
end
|
29
|
+
end
|
30
|
+
def get_haskell_parser
|
31
|
+
if self == TInt then
|
32
|
+
return 'parseInt'
|
33
|
+
elsif self == TLong then
|
34
|
+
return 'parseLong'
|
35
|
+
elsif self == TFloat then
|
36
|
+
return 'parseFloat'
|
37
|
+
elsif self == TDouble then
|
38
|
+
return 'parseDouble'
|
39
|
+
elsif self == TChar then
|
40
|
+
return 'parseChar'
|
41
|
+
elsif self == TString then
|
42
|
+
return 'parseString'
|
43
|
+
elsif self == TBoolean then
|
44
|
+
return 'parseBool'
|
45
|
+
elsif is_a? TArray then
|
46
|
+
return '(parseList ' + subtype.get_haskell_parser + ')'
|
47
|
+
else
|
48
|
+
return 'unknown'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
def dumb_haskell
|
52
|
+
if self == TInt then
|
53
|
+
return '0'
|
54
|
+
elsif self == TLong then
|
55
|
+
return '0'
|
56
|
+
elsif self == TFloat then
|
57
|
+
return '0'
|
58
|
+
elsif self == TDouble then
|
59
|
+
return '0'
|
60
|
+
elsif self == TChar then
|
61
|
+
return "'$'"
|
62
|
+
elsif self == TString then
|
63
|
+
return '"$"'
|
64
|
+
elsif self == TBoolean then
|
65
|
+
return 'True'
|
66
|
+
elsif is_a? TArray then
|
67
|
+
return '[]'
|
68
|
+
else
|
69
|
+
return 'Nil'
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
class HaskellEngine
|
74
|
+
attr_accessor :func, :vars
|
75
|
+
def initialize func, vars
|
76
|
+
@func = Signature.new func.type, func.name.uncapitalize
|
77
|
+
@vars = vars.map do |var|
|
78
|
+
Signature.new var.type, var.name.uncapitalize
|
79
|
+
end
|
80
|
+
end
|
81
|
+
def declare
|
82
|
+
ret = ''
|
83
|
+
ret << func.name << ' :: '
|
84
|
+
|
85
|
+
temp = vars.map do |var| var.type.to_haskell end
|
86
|
+
ret << temp.join(' -> ') << ' -> ' << func.type.to_haskell << "\n"
|
87
|
+
|
88
|
+
ret << func.name << ' '
|
89
|
+
temp = vars.map do |var| var.name end
|
90
|
+
ret << temp.join(' ') << ' = ' << func.type.dumb_haskell
|
91
|
+
|
92
|
+
return ret
|
93
|
+
end
|
94
|
+
def input
|
95
|
+
ret = 'getVars :: Parser ('
|
96
|
+
temp = @vars.map do |var| var.type.to_haskell end
|
97
|
+
ret << temp.join(', ') << ")\n"
|
98
|
+
temp = 'getVars = do '
|
99
|
+
ret << temp
|
100
|
+
indent = ' ' * temp.size
|
101
|
+
temp = @vars.map do |var|
|
102
|
+
x = ''
|
103
|
+
x << var.name
|
104
|
+
x << ' <- spaces >> '
|
105
|
+
x << var.type.get_haskell_parser
|
106
|
+
end
|
107
|
+
ret << temp.join(" ; next\n#{indent}") << "\n"
|
108
|
+
ret << indent << 'return ('
|
109
|
+
temp = @vars.map do |var| var.name end
|
110
|
+
ret << temp.join(', ')
|
111
|
+
ret << ')'
|
112
|
+
return ret
|
113
|
+
end
|
114
|
+
def output
|
115
|
+
ret = ''
|
116
|
+
ret << @func.name << ' '
|
117
|
+
temp = vars.map do |var| var.name end
|
118
|
+
ret << temp.join(' ')
|
119
|
+
return ret
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|