gettc 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|