gettc 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +41 -0
  3. data/bin/gettc +63 -0
  4. data/core/lib/topcoder.rb +3 -0
  5. data/core/lib/topcoder/download.rb +89 -0
  6. data/core/lib/topcoder/generate.rb +131 -0
  7. data/core/lib/topcoder/parse.rb +231 -0
  8. data/core/lib/topcoder/print.rb +56 -0
  9. data/core/lib/topcoder/problem.rb +33 -0
  10. data/core/lib/topcoder/signature.rb +55 -0
  11. data/core/lib/topcoder/types.rb +62 -0
  12. data/core/test/topcoder/download_test.rb +29 -0
  13. data/core/test/topcoder/generate_test.rb +31 -0
  14. data/core/test/topcoder/parse_test.rb +104 -0
  15. data/core/test/topcoder/signature_test.rb +52 -0
  16. data/core/test/topcoder/types_test.rb +24 -0
  17. data/dist/config.yml +2 -0
  18. data/dist/include/cpp/engine.rb +90 -0
  19. data/dist/include/cpp/topcoder +212 -0
  20. data/dist/include/haskell/TopCoder.hs +82 -0
  21. data/dist/include/haskell/engine.rb +122 -0
  22. data/dist/include/java/TopCoder.jar +0 -0
  23. data/dist/include/java/engine.rb +207 -0
  24. data/dist/template/bin/runner.sh +113 -0
  25. data/dist/template/data/demo/{examples_d} +0 -0
  26. data/dist/template/data/sys/{systests_d} +0 -0
  27. data/dist/template/prob/images/{images_d} +0 -0
  28. data/dist/template/prob/{name}.html +8 -0
  29. data/dist/template/prob/{name}.md +1 -0
  30. data/dist/template/solve/cpp/Makefile +30 -0
  31. data/dist/template/solve/cpp/{name}.cpp +11 -0
  32. data/dist/template/solve/cpp/{name}Runner.cpp +26 -0
  33. data/dist/template/solve/cpp/{name}Test.cpp +8 -0
  34. data/dist/template/solve/haskell/Makefile +30 -0
  35. data/dist/template/solve/haskell/{name}.hs +7 -0
  36. data/dist/template/solve/haskell/{name}Runner.hs +27 -0
  37. data/dist/template/solve/haskell/{name}Test.hs +10 -0
  38. data/dist/template/solve/java/build.xml +78 -0
  39. data/dist/template/solve/java/{name}.java +9 -0
  40. data/dist/template/solve/java/{name}Runner.java +32 -0
  41. data/dist/template/solve/java/{name}Test.java +8 -0
  42. data/dist/template/util/check/Makefile +5 -0
  43. data/dist/template/util/check/check.cpp +26 -0
  44. metadata +121 -0
@@ -0,0 +1,56 @@
1
+ require 'topcoder/problem'
2
+ require 'bluecloth'
3
+
4
+ module TopCoder
5
+ class Problem
6
+ def to_md
7
+ out = "# [#{@name}](#{@url})\n"
8
+ out << "*#{@source}*\n\n"
9
+
10
+ out << "## Statement\n"
11
+ out << @statement << "\n\n"
12
+
13
+ if not @definitions.empty? then
14
+ out << "## Definitions\n"
15
+ @definitions.each do |k, v| out << "- *#{k}*: `#{v}`\n" end
16
+ out << "\n"
17
+ end
18
+
19
+ if not @notes.empty? then
20
+ out << "## Notes\n"
21
+ @notes.each do |note| out << "- #{note}\n" end
22
+ out << "\n"
23
+ end
24
+
25
+ if not @constraints.empty? then
26
+ out << "## Constraints\n"
27
+ @constraints.each do |constraint|
28
+ out << "- #{constraint}\n"
29
+ end
30
+ out << "\n"
31
+ end
32
+
33
+ if not @examples.empty? then
34
+ out << "## Examples\n"
35
+ @examples.each_index do |i|
36
+ example = @examples[i]
37
+ out << "### Example #{i + 1}\n"
38
+ out << "#### Input\n<c>"
39
+ out << example.input.gsub("\n", '<br />')
40
+ out << "</c>\n"
41
+ out << "#### Output\n<c>"
42
+ out << example.output.gsub("\n", '<br />')
43
+ out << "</c>\n"
44
+ if not example.reason.empty? then
45
+ out << "#### Reason\n#{example.reason}\n\n"
46
+ end
47
+ end
48
+ end
49
+ return out
50
+ end
51
+ def to_html
52
+ bc = BlueCloth.new to_md
53
+ return bc.to_html
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,33 @@
1
+ module TopCoder
2
+ class Case
3
+ attr_accessor :input, :output, :reason
4
+ def initialize
5
+ @input = ''
6
+ @output = ''
7
+ @reason = ''
8
+ end
9
+ end
10
+ class Image
11
+ attr_accessor :name, :content
12
+ def initialize
13
+ @name = ''
14
+ @content = ''
15
+ end
16
+ end
17
+ class Problem
18
+ attr_accessor :name, :url, :source, :statement, :definitions, :notes,
19
+ :constraints, :examples, :systests, :images
20
+ def initialize
21
+ @name = ''
22
+ @url = ''
23
+ @source = ''
24
+ @statement = ''
25
+ @definitions = { }
26
+ @notes = []
27
+ @constraints = []
28
+ @examples = []
29
+ @systests = []
30
+ @images = []
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,55 @@
1
+ require 'topcoder/types'
2
+
3
+ module TopCoder
4
+ class SignatureError < StandardError
5
+ end
6
+ class CannotParseSignature < SignatureError
7
+ attr_accessor :source
8
+ def initialize source, msg = 'Cannot parse signature'
9
+ @source = source
10
+ super "#{msg} (#{source}"
11
+ end
12
+ end
13
+ class InvalidVariableName < SignatureError
14
+ attr_accessor :name
15
+ def initialize name, msg = 'Invalid variable name'
16
+ @name = name
17
+ super "#{msg} (#{name})"
18
+ end
19
+ end
20
+ class Signature
21
+ attr_accessor :type, :name
22
+ def initialize type, name
23
+ @type = type
24
+ @name = name
25
+ end
26
+ end
27
+ def parse_signature str
28
+ str.strip!
29
+ parts = str.split
30
+ raise CannotParseSignature.new str if parts.size != 2
31
+ type = parse_type parts[0]
32
+ name = parts[1]
33
+ if name =~ /^[a-zA-Z_]\w*$/
34
+ return Signature.new type, name
35
+ else
36
+ raise InvalidVariableName.new name
37
+ end
38
+ end
39
+ def parse_method_signature str
40
+ str.strip!
41
+ sigs = []
42
+ parts = str.split '('
43
+ raise CannotParseSignature.new str if parts.size != 2
44
+ sigs << parse_signature(parts[0])
45
+
46
+ str = parts[1]
47
+ raise CannotParseSignature.new str if str[-1] != ')'
48
+ str.chop!
49
+
50
+ parts = str.split ','
51
+ parts.each do |sig| sigs << parse_signature(sig) end
52
+
53
+ return sigs
54
+ end
55
+ end
@@ -0,0 +1,62 @@
1
+ require 'singleton'
2
+
3
+ module TopCoder
4
+ class TypeError < StandardError
5
+ end
6
+ class UnrecognizedType < TypeError
7
+ attr_accessor :type
8
+ def initialize type = nil, msg = 'Not a valid TopCoder type'
9
+ @type = type
10
+ super "#{msg} (#{type})"
11
+ end
12
+ end
13
+ class Type
14
+ def initialize is_object
15
+ @is_object = is_object
16
+ end
17
+ def obj?
18
+ return @is_object
19
+ end
20
+ end
21
+ TBoolean = Type.new false
22
+ TInt = Type.new false
23
+ TLong = Type.new false
24
+ TFloat = Type.new false
25
+ TDouble = Type.new false
26
+ TChar = Type.new false
27
+ TString = Type.new true
28
+ class TArray < Type
29
+ attr_accessor :subtype
30
+ def initialize subtype
31
+ raise UnrecognizedType.new subtype if not subtype.is_a? Type
32
+ @subtype = subtype
33
+ end
34
+ def == ary
35
+ return false if not ary.is_a? TArray
36
+ return @subtype == ary.subtype
37
+ end
38
+ def obj?
39
+ return true
40
+ end
41
+ end
42
+ def parse_type str
43
+ return TArray.new parse_type str[0 .. -3] if str[-2 .. -1] == '[]'
44
+ case str
45
+ when 'boolean'
46
+ return TBoolean
47
+ when 'int'
48
+ return TInt
49
+ when 'long'
50
+ return TLong
51
+ when 'float'
52
+ return TFloat
53
+ when 'double'
54
+ return TDouble
55
+ when 'char'
56
+ return TChar
57
+ when 'String'
58
+ return TString
59
+ end
60
+ raise UnrecognizedType.new str
61
+ end
62
+ end
@@ -0,0 +1,29 @@
1
+ require 'test/unit'
2
+ require 'topcoder/download'
3
+ include TopCoder
4
+
5
+ class DownloadTest < Test::Unit::TestCase
6
+ def setup
7
+ @account = Account.new 'gettc', 'algorithm'
8
+ end
9
+ def test_wrong_account
10
+ assert_raises LoginFailed do
11
+ Downloader.new Account.new 'username', 'password'
12
+ end
13
+ end
14
+ def test_wrong_id
15
+ assert_raises IDNotAvailable do
16
+ (Downloader.new @account).download_problem 1000000
17
+ end
18
+ end
19
+ def test_download_ok
20
+ ids = [10297, 10324, 10329, 10330, 10505, 10685, 10686, 10690, 11264,
21
+ 11266, 11303, 11315, 11322, 11350, 11357, 11419, 8763, 8819, 9995]
22
+ downloader = Downloader.new @account
23
+ 3.times do
24
+ id = ids[rand ids.size]
25
+ html = downloader.download_problem id
26
+ assert_match '<h3>Problem Statement</h3>', html
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,31 @@
1
+ require 'test/unit'
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+
5
+ require 'topcoder/generate'
6
+ include TopCoder
7
+
8
+ class GenerateTest < Test::Unit::TestCase
9
+ def setup
10
+ @source_d = File.join File.dirname(__FILE__), '../../../dist/template'
11
+ @target_d = File.join Dir.tmpdir, 'gettc'
12
+ FileUtils.mkdir @target_d if not File.directory? @target_d
13
+ @generator = Generator.new @source_d, @target_d
14
+ end
15
+ def test_initialize
16
+ assert_raise SourceDirNotExist do
17
+ Generator.new 'this_directory_must_not_exist', @target_d
18
+ end
19
+ assert_raise TargetDirNotExist do
20
+ Generator.new @source_d, 'this_directory_must_not_exist'
21
+ end
22
+ end
23
+ def test_prob_dir_exists
24
+ prob = Problem.new
25
+ prob.name = 'JustATest'
26
+ prob_d = File.join @target_d, prob.name
27
+ FileUtils.mkdir prob_d if not File.exists? prob_d
28
+ assert_raise ProblemDirExists do @generator.generate prob end
29
+ FileUtils.rmdir prob_d
30
+ end
31
+ end
@@ -0,0 +1,104 @@
1
+ require 'test/unit'
2
+ require 'topcoder/parse'
3
+ include TopCoder
4
+
5
+ class ParseTest < Test::Unit::TestCase
6
+ def setup
7
+ downloader = Downloader.new Account.new 'gettc', 'algorithm'
8
+ @parser = Parser.new downloader
9
+ @datadir = File.join File.dirname(__FILE__), '../../files/stats'
10
+ end
11
+ def get_problem_raw prob
12
+ return File.read File.join @datadir, prob + '.htm'
13
+ end
14
+ def test_indexes
15
+ assert_equal [0, 3], @parser.indexes('abcde', 'bc')
16
+ assert_equal nil, @parser.indexes('abcde', 'f')
17
+ end
18
+ def test_filter
19
+ assert_equal 'Lorem Ipsum', @parser.filter('<xml> Lorem Ipsum </xml> ')
20
+ assert_equal '2^(3)', @parser.filter('2<sup>3</sup>')
21
+ assert_equal '*hi*', @parser.filter(' <b>hi</b>')
22
+ html = <<-END
23
+ <img src=
24
+ "http://www.topcoder.com/contest/problem/CirclesCountry/case1.gif">
25
+ END
26
+ assert_equal '![image](images/case1.gif)', @parser.filter(html)
27
+ end
28
+ def test_PageNumbers
29
+ html = get_problem_raw 'PageNumbers'
30
+ prob = @parser.parse html
31
+ assert_equal 'PageNumbers', prob.name
32
+ assert_equal 5, prob.definitions.size
33
+ assert_equal 1, prob.notes.size
34
+ assert_equal 1, prob.constraints.size
35
+ assert_equal 5, prob.examples.size
36
+ assert_equal 118, prob.systests.size
37
+ assert_equal 0, prob.images.size
38
+ end
39
+ def test_CirclesCountry
40
+ html = get_problem_raw 'CirclesCountry'
41
+ prob = @parser.parse html
42
+ assert_equal 'CirclesCountry', prob.name
43
+ assert_equal 5, prob.definitions.size
44
+ assert_equal 0, prob.notes.size
45
+ assert_equal 7, prob.constraints.size
46
+ assert_equal 5, prob.examples.size
47
+ assert_equal 228, prob.systests.size
48
+ assert_equal 4, prob.images.size
49
+ end
50
+ def test_TheTournamentDivOne
51
+ html = get_problem_raw 'TheTournamentDivOne'
52
+ prob = @parser.parse html
53
+ assert_equal 'TheTournamentDivOne', prob.name
54
+ assert_equal 5, prob.definitions.size
55
+ assert_equal 0, prob.notes.size
56
+ assert_equal 4, prob.constraints.size
57
+ assert_equal 4, prob.examples.size
58
+ assert_equal 0, prob.systests.size
59
+ assert_equal 0, prob.images.size
60
+ end
61
+ def test_FunnyGames
62
+ html = get_problem_raw 'FunnyGames'
63
+ prob = @parser.parse html
64
+ assert_equal 'FunnyGames', prob.name
65
+ assert_equal 5, prob.definitions.size
66
+ assert_equal 0, prob.notes.size
67
+ assert_equal 6, prob.constraints.size
68
+ assert_equal 5, prob.examples.size
69
+ assert_equal 0, prob.systests.size
70
+ assert_equal 0, prob.images.size
71
+ end
72
+ def test_BuildingRoads
73
+ html = get_problem_raw 'BuildingRoads'
74
+ prob = @parser.parse html
75
+ assert_equal 'BuildingRoads', prob.name
76
+ assert_equal 5, prob.definitions.size
77
+ assert_equal 2, prob.notes.size
78
+ assert_equal 10, prob.constraints.size
79
+ assert_equal 5, prob.examples.size
80
+ assert_equal 0, prob.systests.size
81
+ assert_equal 2, prob.images.size
82
+ end
83
+ def test_Acronyms
84
+ html = get_problem_raw 'Acronyms'
85
+ prob = @parser.parse html
86
+ assert_equal 'Acronyms', prob.name
87
+ assert_equal 5, prob.definitions.size
88
+ assert_equal 1, prob.notes.size
89
+ assert_equal 8, prob.constraints.size
90
+ assert_equal 8, prob.examples.size
91
+ assert_equal 39, prob.systests.size
92
+ assert_equal 0, prob.images.size
93
+ end
94
+ def test_BackyardTrees
95
+ html = get_problem_raw 'BackyardTrees'
96
+ prob = @parser.parse html
97
+ assert_equal 'BackyardTrees', prob.name
98
+ assert_equal 5, prob.definitions.size
99
+ assert_equal 0, prob.notes.size
100
+ assert_equal 4, prob.constraints.size
101
+ assert_equal 6, prob.examples.size
102
+ assert_equal 2, prob.images.size
103
+ end
104
+ end
@@ -0,0 +1,52 @@
1
+ require 'test/unit'
2
+ require 'topcoder/signature'
3
+ include TopCoder
4
+
5
+ class SignatureTest < Test::Unit::TestCase
6
+ def test_parse_signature
7
+ assert_raise CannotParseSignature do
8
+ parse_signature 'invalid_signature'
9
+ end
10
+ assert_raise UnrecognizedType do
11
+ parse_signature 'strange_type name'
12
+ end
13
+ assert_raise InvalidVariableName do
14
+ parse_signature 'int not&ok&name'
15
+ end
16
+ assert_raise InvalidVariableName do parse_signature 'int 0zero' end
17
+ sig = parse_signature 'String[] a_valid_nam3'
18
+ assert_equal TArray.new(TString), sig.type
19
+ assert_equal 'a_valid_nam3', sig.name
20
+ end
21
+ def test_parse_method_signature
22
+ assert_raise CannotParseSignature do
23
+ parse_method_signature 'there are no brackets'
24
+ end
25
+ assert_raise CannotParseSignature do
26
+ parse_method_signature 'int main(int main())'
27
+ end
28
+ assert_raise CannotParseSignature do
29
+ parse_method_signature 'int main(oops forget to close bracket'
30
+ end
31
+ method = ' int leastBorders(String[] X , int[] Y, double[] R,'
32
+ method += ' char my_x1, long y1 , float x2, int[][] y2) '
33
+ sigs = parse_method_signature method
34
+ assert_equal 8, sigs.size
35
+ assert_equal TInt, sigs[0].type
36
+ assert_equal 'leastBorders', sigs[0].name
37
+ assert_equal TArray.new(TString), sigs[1].type
38
+ assert_equal 'X', sigs[1].name
39
+ assert_equal TArray.new(TInt), sigs[2].type
40
+ assert_equal 'Y', sigs[2].name
41
+ assert_equal TArray.new(TDouble), sigs[3].type
42
+ assert_equal 'R', sigs[3].name
43
+ assert_equal TChar, sigs[4].type
44
+ assert_equal 'my_x1', sigs[4].name
45
+ assert_equal TLong, sigs[5].type
46
+ assert_equal 'y1', sigs[5].name
47
+ assert_equal TFloat, sigs[6].type
48
+ assert_equal 'x2', sigs[6].name
49
+ assert_equal TArray.new(TArray.new(TInt)), sigs[7].type
50
+ assert_equal 'y2', sigs[7].name
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ require 'test/unit'
2
+ require 'topcoder/types'
3
+ include TopCoder
4
+
5
+ class TypesTest < Test::Unit::TestCase
6
+ def test_parse_type
7
+ assert_raise UnrecognizedType do array = TArray.new 123 end
8
+ assert_raise UnrecognizedType do type = parse_type '' end
9
+ assert_raise UnrecognizedType do type = parse_type ' ' end
10
+ assert_raise UnrecognizedType do type = parse_type '[]' end
11
+ assert_raise UnrecognizedType do type = parse_type 'vector' end
12
+ assert_raise UnrecognizedType do type = parse_type 'vector[]' end
13
+ assert_equal TBoolean, parse_type('boolean')
14
+ assert_equal TInt, parse_type('int')
15
+ assert_equal TLong, parse_type('long')
16
+ assert_equal TFloat, parse_type('float')
17
+ assert_equal TDouble, parse_type('double')
18
+ assert_equal TChar, parse_type('char')
19
+ assert_equal TString, parse_type('String')
20
+ assert_equal TArray.new(TBoolean), parse_type('boolean[]')
21
+ assert_equal TArray.new(TInt), parse_type('int[]')
22
+ assert_equal TArray.new(TArray.new(TString)), parse_type('String[][]')
23
+ end
24
+ end