gettc 1.5 → 1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/gettc +45 -29
- data/core/lib/gettc.rb +7 -0
- data/core/lib/{topcoder → gettc}/download.rb +53 -45
- data/core/lib/gettc/generate.rb +145 -0
- data/core/lib/{topcoder → gettc}/parse.rb +104 -102
- data/core/lib/{topcoder → gettc}/print.rb +11 -11
- data/core/lib/{topcoder → gettc}/problem.rb +11 -11
- data/core/lib/{topcoder → gettc}/signature.rb +8 -8
- data/core/lib/{topcoder → gettc}/types.rb +34 -17
- data/core/test/{topcoder → gettc}/download_test.rb +6 -6
- data/core/test/gettc/generate_test.rb +31 -0
- data/core/test/{topcoder → gettc}/parse_test.rb +26 -26
- data/core/test/gettc/signature_test.rb +54 -0
- data/core/test/gettc/types_test.rb +24 -0
- data/dist/config.yml +1 -0
- data/dist/include/cpp/engine.rb +32 -32
- data/dist/include/cpp/topcoder +89 -25
- data/dist/include/haskell/TopCoder.hs +72 -53
- data/dist/include/haskell/engine.rb +49 -47
- data/dist/include/java/TopCoder.jar +0 -0
- data/dist/include/java/engine.rb +71 -71
- data/dist/include/python/engine.rb +46 -0
- data/dist/include/python/topcoder/__init__.py +3 -0
- data/dist/include/python/topcoder/errors.py +4 -0
- data/dist/include/python/topcoder/reader.py +160 -0
- data/dist/include/python/topcoder/writer.py +13 -0
- data/dist/template/bin/runner.sh +16 -6
- data/dist/template/solve/cpp/Makefile +9 -5
- data/dist/template/solve/cpp/{name}.cpp +8 -8
- data/dist/template/solve/cpp/{name}Runner.cpp +8 -8
- data/dist/template/solve/haskell/Makefile +9 -5
- data/dist/template/solve/haskell/{name}.hs +1 -1
- data/dist/template/solve/haskell/{name}Runner.hs +5 -5
- data/dist/template/solve/java/Makefile +18 -0
- data/dist/template/solve/java/build.xml +7 -3
- data/dist/template/solve/java/{name}.java +1 -1
- data/dist/template/solve/java/{name}Runner.java +1 -1
- data/dist/template/solve/python/Makefile +27 -0
- data/dist/template/solve/python/{name}.py +4 -0
- data/dist/template/solve/python/{name}Runner.py +27 -0
- data/dist/template/util/check/Makefile +3 -1
- data/dist/usage +5 -0
- metadata +30 -24
- data/Rakefile +0 -41
- data/core/lib/topcoder.rb +0 -3
- data/core/lib/topcoder/generate.rb +0 -131
- data/core/test/topcoder/generate_test.rb +0 -31
- data/core/test/topcoder/signature_test.rb +0 -52
- data/core/test/topcoder/types_test.rb +0 -24
- data/dist/template/solve/cpp/{name}Test.cpp +0 -8
- data/dist/template/solve/haskell/{name}Test.hs +0 -10
- data/dist/template/solve/java/{name}Test.java +0 -8
@@ -0,0 +1,160 @@
|
|
1
|
+
from topcoder.errors import UnsupportedTypeError
|
2
|
+
|
3
|
+
class ReadError(Exception):
|
4
|
+
def __init__(self, text, pos, info = ""):
|
5
|
+
if (pos < len(text)) and (pos >= 0):
|
6
|
+
text = text[:pos] + "|" + text[pos] + "|" + text[(pos + 1):]
|
7
|
+
message = "<" + text + ">"
|
8
|
+
if info:
|
9
|
+
message += " (" + info + ")"
|
10
|
+
Exception.__init__(self, message)
|
11
|
+
|
12
|
+
class Reader(object):
|
13
|
+
def __init__(self, text):
|
14
|
+
self._internal = ReaderInternal(text)
|
15
|
+
|
16
|
+
def next(self, type = None):
|
17
|
+
return self._internal.next(type)
|
18
|
+
|
19
|
+
class ReaderInternal(object):
|
20
|
+
def __init__(self, text):
|
21
|
+
self.text = text
|
22
|
+
self.pos = 0
|
23
|
+
self.len = len(text)
|
24
|
+
|
25
|
+
def next(self, type = None):
|
26
|
+
if type is None:
|
27
|
+
self.spaces()
|
28
|
+
self.expect(',')
|
29
|
+
return
|
30
|
+
|
31
|
+
if type == "int" or type == "long":
|
32
|
+
return self.next_int()
|
33
|
+
if type == "float" or type == "double":
|
34
|
+
return self.next_float()
|
35
|
+
if type == "char":
|
36
|
+
return self.next_char()
|
37
|
+
if type == "String":
|
38
|
+
return self.next_string()
|
39
|
+
if type == "boolean":
|
40
|
+
return self.next_boolean()
|
41
|
+
if type.endswith("[]"):
|
42
|
+
return self.next_array(type[:-2])
|
43
|
+
|
44
|
+
raise UnsupportedTypeError(type)
|
45
|
+
|
46
|
+
def raise_here(self, message):
|
47
|
+
raise ReadError(self.text, self.pos, message)
|
48
|
+
|
49
|
+
def check_pos(self):
|
50
|
+
if self.pos >= self.len:
|
51
|
+
self.raise_here("unexpected end of input")
|
52
|
+
|
53
|
+
def token(self):
|
54
|
+
self.check_pos()
|
55
|
+
return self.text[self.pos]
|
56
|
+
|
57
|
+
def spaces(self):
|
58
|
+
while self.pos < self.len and self.token().isspace():
|
59
|
+
self.pos += 1
|
60
|
+
|
61
|
+
def next_digits(self):
|
62
|
+
if not self.token().isdigit():
|
63
|
+
self.raise_here("expecting a digit")
|
64
|
+
begin = self.pos
|
65
|
+
while True:
|
66
|
+
self.pos += 1
|
67
|
+
if self.pos == self.len or not self.token().isdigit():
|
68
|
+
break
|
69
|
+
return self.text[begin:self.pos]
|
70
|
+
|
71
|
+
def next_positive_int(self):
|
72
|
+
return int(self.next_digits())
|
73
|
+
|
74
|
+
def next_int(self):
|
75
|
+
self.spaces()
|
76
|
+
if self.token() == "-":
|
77
|
+
self.pos += 1
|
78
|
+
return -self.next_positive_int()
|
79
|
+
return self.next_positive_int()
|
80
|
+
|
81
|
+
def next_positive_float(self):
|
82
|
+
s = self.next_digits()
|
83
|
+
if self.pos < self.len:
|
84
|
+
if self.token() == ".":
|
85
|
+
self.pos += 1
|
86
|
+
s += "." + self.next_digits()
|
87
|
+
return float(s)
|
88
|
+
|
89
|
+
def next_float(self):
|
90
|
+
self.spaces()
|
91
|
+
if self.token() == "-":
|
92
|
+
self.pos += 1
|
93
|
+
return -self.next_positive_float()
|
94
|
+
return self.next_positive_float()
|
95
|
+
|
96
|
+
def expect(self, c):
|
97
|
+
if self.token() == c:
|
98
|
+
self.pos += 1
|
99
|
+
else:
|
100
|
+
self.raise_here("expecting <" + c + ">")
|
101
|
+
|
102
|
+
def next_char(self):
|
103
|
+
self.spaces()
|
104
|
+
self.expect("'")
|
105
|
+
c = self.token()
|
106
|
+
self.pos += 1
|
107
|
+
self.expect("'")
|
108
|
+
return c
|
109
|
+
|
110
|
+
def next_boolean(self):
|
111
|
+
self.spaces()
|
112
|
+
if self.text[self.pos:self.pos + 4].upper() == "TRUE":
|
113
|
+
self.pos += 4
|
114
|
+
return True
|
115
|
+
elif self.text[self.pos:self.pos + 5].upper() == "FALSE":
|
116
|
+
self.pos += 5
|
117
|
+
return False
|
118
|
+
self.raise_here("expecting either true or false)")
|
119
|
+
|
120
|
+
def next_string(self):
|
121
|
+
self.spaces()
|
122
|
+
self.expect('"')
|
123
|
+
begin = self.pos
|
124
|
+
while True:
|
125
|
+
if self.pos >= self.len:
|
126
|
+
self.raise_here("expecting a closing quote when reading a string")
|
127
|
+
if self.token() == '"':
|
128
|
+
self.pos += 1
|
129
|
+
saved = self.pos
|
130
|
+
self.spaces()
|
131
|
+
if self.pos == self.len or self.token() == ',' or self.token() == ']':
|
132
|
+
self.pos = saved
|
133
|
+
return self.text[begin:self.pos - 1]
|
134
|
+
else:
|
135
|
+
self.pos += 1
|
136
|
+
|
137
|
+
def next_elems(self, elem_type, array):
|
138
|
+
self.spaces()
|
139
|
+
c = self.token()
|
140
|
+
if c == "]":
|
141
|
+
self.pos += 1
|
142
|
+
return
|
143
|
+
elif c == ",":
|
144
|
+
self.pos += 1
|
145
|
+
array.append(self.next(elem_type))
|
146
|
+
self.next_elems(elem_type, array)
|
147
|
+
else:
|
148
|
+
self.raise_here("expecting either <,> or <]>")
|
149
|
+
|
150
|
+
def next_array(self, elem_type):
|
151
|
+
result = []
|
152
|
+
self.spaces()
|
153
|
+
self.expect("[")
|
154
|
+
self.spaces()
|
155
|
+
if self.token() == "]":
|
156
|
+
self.pos += 1
|
157
|
+
return result
|
158
|
+
result.append(self.next(elem_type))
|
159
|
+
self.next_elems(elem_type, result)
|
160
|
+
return result
|
@@ -0,0 +1,13 @@
|
|
1
|
+
from topcoder.errors import UnsupportedTypeError
|
2
|
+
|
3
|
+
def write(value, type):
|
4
|
+
if type in ["int", "long", "float", "double", "boolean"]:
|
5
|
+
return str(value)
|
6
|
+
elif type == "char":
|
7
|
+
return "'" + value + "'"
|
8
|
+
elif type == "String":
|
9
|
+
return '"' + value + '"'
|
10
|
+
elif type.endswith("[]"):
|
11
|
+
elem_type = type[:-2]
|
12
|
+
return "[" + ", ".join(map(lambda elem: write(elem, elem_type), value)) + "]"
|
13
|
+
raise UnsupportedTypeError(type)
|
data/dist/template/bin/runner.sh
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# runner.sh mode /path/to/solver /path/to/input/dir /path/to/output/dir
|
2
|
+
# mode = quiet|verbose|file
|
3
|
+
|
1
4
|
mode="$1"
|
2
5
|
solver="$2"
|
3
6
|
data_d="$3"
|
@@ -5,14 +8,20 @@ output_d="$4"
|
|
5
8
|
ostream=/dev/null
|
6
9
|
|
7
10
|
timeit () {
|
8
|
-
if [ -
|
9
|
-
/usr/bin/time -o
|
11
|
+
if [ command -v /usr/bin/time >/dev/null 2>&1 ]; then
|
12
|
+
/usr/bin/time -o /dev/null echo "Testing availability of the time command" >/dev/null
|
13
|
+
if [ $? -eq 0 ]; then
|
14
|
+
/usr/bin/time -o $ostream "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
|
15
|
+
return
|
16
|
+
fi
|
10
17
|
elif [ $mode = 'verbose' ]; then
|
11
|
-
|
12
|
-
|
13
|
-
|
18
|
+
if [ command -v time >/dev/null 2>&1 ]; then
|
19
|
+
time "$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
|
20
|
+
return
|
21
|
+
fi
|
14
22
|
fi
|
15
|
-
|
23
|
+
"$1" "$2" "$3" "$4" "$5" "$6" "$7" "$8" "$9"
|
24
|
+
}
|
16
25
|
|
17
26
|
puts () {
|
18
27
|
echo "$1" > $ostream
|
@@ -109,5 +118,6 @@ main () {
|
|
109
118
|
fi
|
110
119
|
|
111
120
|
}
|
121
|
+
|
112
122
|
init
|
113
123
|
main
|
@@ -1,11 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
GETTC_HOME ?= $(HOME)/.gettc
|
2
|
+
OUTPUT_D =../../build/cpp
|
3
|
+
DATA_D = ../../data
|
4
|
+
COMPILER = g++ -std=gnu++0x -I$(GETTC_HOME)/include/cpp
|
5
|
+
RUNNER = sh ../../bin/runner.sh
|
5
6
|
|
6
7
|
run = $(RUNNER) $1 $(OUTPUT_D)/<%= prob.name %>Runner $(DATA_D)/$2 $(OUTPUT_D)/$2
|
7
8
|
|
8
|
-
default :
|
9
|
+
default : usage
|
10
|
+
|
11
|
+
usage :
|
12
|
+
@cat $(GETTC_HOME)/usage
|
9
13
|
|
10
14
|
setup :
|
11
15
|
if [ ! -d $(OUTPUT_D) ]; then mkdir -p $(OUTPUT_D); fi
|
@@ -1,11 +1,11 @@
|
|
1
1
|
#include <vector>
|
2
2
|
#include <string>
|
3
3
|
using namespace std;
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
<%=
|
8
|
-
engine.declare
|
9
|
-
|
10
|
-
|
11
|
-
}
|
4
|
+
|
5
|
+
class <%= prob.name %> {
|
6
|
+
public:
|
7
|
+
<%= engine = CppEngine.new func, vars
|
8
|
+
engine.declare %> {
|
9
|
+
return <%= func.type.dumb_cpp %>;
|
10
|
+
}
|
11
|
+
};
|
@@ -1,26 +1,26 @@
|
|
1
|
+
#include <fstream>
|
1
2
|
#include <topcoder>
|
2
|
-
using namespace TopCoder;
|
3
3
|
#include "<%= prob.name %>.cpp"
|
4
|
-
|
5
|
-
using namespace std;
|
4
|
+
namespace tc = TopCoder;
|
6
5
|
<%
|
7
6
|
engine = CppEngine.new func, vars
|
8
7
|
%>
|
9
8
|
int main(int argc, char const *argv[]) {
|
10
9
|
try {
|
11
|
-
ifstream ifs(argv[1]);
|
10
|
+
std::ifstream ifs(argv[1]);
|
12
11
|
<%=
|
13
12
|
engine.input.gsub(/^/, ' ' * 8)
|
14
13
|
%>
|
15
14
|
ifs.close();
|
16
15
|
|
17
|
-
ofstream ofs(argv[2]);
|
16
|
+
std::ofstream ofs(argv[2]);
|
17
|
+
<%= prob.name %> solver;
|
18
18
|
<%=
|
19
19
|
engine.output.gsub(/^/, ' ' * 8)
|
20
20
|
%>
|
21
21
|
ofs.close();
|
22
|
-
} catch (exception &e) {
|
23
|
-
cerr << e.what() << endl;
|
22
|
+
} catch (std::exception &e) {
|
23
|
+
std::cerr << e.what() << std::endl;
|
24
24
|
}
|
25
25
|
return 0;
|
26
|
-
}
|
26
|
+
}
|
@@ -1,11 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
1
|
+
GETTC_HOME ?= $(HOME)/.gettc
|
2
|
+
OUTPUT_D = ../../build/haskell
|
3
|
+
DATA_D = ../../data
|
4
|
+
COMPILER = ghc -i$(GETTC_HOME)/include/haskell -outputdir $(OUTPUT_D)
|
5
|
+
RUNNER = sh ../../bin/runner.sh
|
5
6
|
|
6
7
|
run = $(RUNNER) $1 $(OUTPUT_D)/<%= prob.name %>Runner $(DATA_D)/$2 $(OUTPUT_D)/$2
|
7
8
|
|
8
|
-
default :
|
9
|
+
default : usage
|
10
|
+
|
11
|
+
usage :
|
12
|
+
@cat $(GETTC_HOME)/usage
|
9
13
|
|
10
14
|
setup :
|
11
15
|
if [ ! -d $(OUTPUT_D) ]; then mkdir -p $(OUTPUT_D); fi
|
@@ -1,7 +1,7 @@
|
|
1
|
-
import TopCoder
|
2
1
|
import System.Environment (getArgs)
|
3
2
|
import System.IO
|
4
|
-
import
|
3
|
+
import qualified TopCoder as TC
|
4
|
+
import qualified <%= prob.name %> (<%= func.name %>)
|
5
5
|
<%
|
6
6
|
engine = HaskellEngine.new func, vars
|
7
7
|
%>
|
@@ -13,15 +13,15 @@ main = do
|
|
13
13
|
args <- getArgs
|
14
14
|
hIn <- openFile (head args) ReadMode
|
15
15
|
contents <- hGetContents hIn
|
16
|
-
case (parse getVars "variables" contents) of
|
16
|
+
case (TC.parse getVars "parse variables" contents) of
|
17
17
|
Left err -> print err
|
18
18
|
Right (<%=
|
19
19
|
temp = engine.vars.map do |var| var.name end
|
20
20
|
temp.join(', ')
|
21
21
|
%>) -> do
|
22
22
|
hOut <- openFile (head (tail args)) WriteMode
|
23
|
-
hPutStr hOut $ show $ <%=
|
23
|
+
hPutStr hOut $ show $ <%= prob.name %>.<%=
|
24
24
|
engine.output
|
25
25
|
%>
|
26
26
|
hClose hOut
|
27
|
-
hClose hIn
|
27
|
+
hClose hIn
|
@@ -1,9 +1,13 @@
|
|
1
1
|
<project name="<%= prob.name %>" basedir="." default="demo">
|
2
2
|
<property environment="env"/>
|
3
|
-
|
3
|
+
|
4
|
+
<condition property="gettc.home" value="${env.GETTC_HOME}" else="${env.HOME}/.gettc">
|
5
|
+
<isset property="env.GETTC_HOME" />
|
6
|
+
</condition>
|
7
|
+
|
4
8
|
<property name="data.dir" value="${basedir}/../../data"/>
|
5
9
|
<property name="output.dir" value="${basedir}/../../build/java"/>
|
6
|
-
<property name="lib" value="${
|
10
|
+
<property name="lib" value="${gettc.home}/include/java/TopCoder.jar"/>
|
7
11
|
<property name="java.sh" value="${output.dir}/java.sh"/>
|
8
12
|
<property name="runner.sh" value="${basedir}/../../bin/runner.sh"/>
|
9
13
|
|
@@ -75,4 +79,4 @@ java -cp "`dirname $0`${path.separator}${lib}" <%= prob.name %>Runner $$*
|
|
75
79
|
<target name="clean">
|
76
80
|
<delete dir="${output.dir}"/>
|
77
81
|
</target>
|
78
|
-
</project>
|
82
|
+
</project>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
GETTC_HOME ?= $(HOME)/.gettc
|
2
|
+
OUTPUT_D = ../../build/python
|
3
|
+
DATA_D = ../../data
|
4
|
+
RUNNER = sh ../../bin/runner.sh
|
5
|
+
|
6
|
+
run = $(RUNNER) $1 ./<%= prob.name %>Runner.py $(DATA_D)/$2 $(OUTPUT_D)/$2
|
7
|
+
|
8
|
+
setup :
|
9
|
+
if [ ! -d $(OUTPUT_D) ]; then mkdir -p $(OUTPUT_D); fi
|
10
|
+
chmod +x <%= prob.name %>Runner.py
|
11
|
+
|
12
|
+
default : usage
|
13
|
+
|
14
|
+
usage :
|
15
|
+
@cat $(GETTC_HOME)/usage
|
16
|
+
|
17
|
+
demo : setup
|
18
|
+
$(call run,verbose,demo)
|
19
|
+
|
20
|
+
sys : setup
|
21
|
+
$(call run,quiet,sys)
|
22
|
+
|
23
|
+
sysv : setup
|
24
|
+
$(call run,verbose,sys)
|
25
|
+
|
26
|
+
clean :
|
27
|
+
rm -rf $(OUTPUT_D)
|