gettc 1.5 → 1.6

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/bin/gettc +45 -29
  3. data/core/lib/gettc.rb +7 -0
  4. data/core/lib/{topcoder → gettc}/download.rb +53 -45
  5. data/core/lib/gettc/generate.rb +145 -0
  6. data/core/lib/{topcoder → gettc}/parse.rb +104 -102
  7. data/core/lib/{topcoder → gettc}/print.rb +11 -11
  8. data/core/lib/{topcoder → gettc}/problem.rb +11 -11
  9. data/core/lib/{topcoder → gettc}/signature.rb +8 -8
  10. data/core/lib/{topcoder → gettc}/types.rb +34 -17
  11. data/core/test/{topcoder → gettc}/download_test.rb +6 -6
  12. data/core/test/gettc/generate_test.rb +31 -0
  13. data/core/test/{topcoder → gettc}/parse_test.rb +26 -26
  14. data/core/test/gettc/signature_test.rb +54 -0
  15. data/core/test/gettc/types_test.rb +24 -0
  16. data/dist/config.yml +1 -0
  17. data/dist/include/cpp/engine.rb +32 -32
  18. data/dist/include/cpp/topcoder +89 -25
  19. data/dist/include/haskell/TopCoder.hs +72 -53
  20. data/dist/include/haskell/engine.rb +49 -47
  21. data/dist/include/java/TopCoder.jar +0 -0
  22. data/dist/include/java/engine.rb +71 -71
  23. data/dist/include/python/engine.rb +46 -0
  24. data/dist/include/python/topcoder/__init__.py +3 -0
  25. data/dist/include/python/topcoder/errors.py +4 -0
  26. data/dist/include/python/topcoder/reader.py +160 -0
  27. data/dist/include/python/topcoder/writer.py +13 -0
  28. data/dist/template/bin/runner.sh +16 -6
  29. data/dist/template/solve/cpp/Makefile +9 -5
  30. data/dist/template/solve/cpp/{name}.cpp +8 -8
  31. data/dist/template/solve/cpp/{name}Runner.cpp +8 -8
  32. data/dist/template/solve/haskell/Makefile +9 -5
  33. data/dist/template/solve/haskell/{name}.hs +1 -1
  34. data/dist/template/solve/haskell/{name}Runner.hs +5 -5
  35. data/dist/template/solve/java/Makefile +18 -0
  36. data/dist/template/solve/java/build.xml +7 -3
  37. data/dist/template/solve/java/{name}.java +1 -1
  38. data/dist/template/solve/java/{name}Runner.java +1 -1
  39. data/dist/template/solve/python/Makefile +27 -0
  40. data/dist/template/solve/python/{name}.py +4 -0
  41. data/dist/template/solve/python/{name}Runner.py +27 -0
  42. data/dist/template/util/check/Makefile +3 -1
  43. data/dist/usage +5 -0
  44. metadata +30 -24
  45. data/Rakefile +0 -41
  46. data/core/lib/topcoder.rb +0 -3
  47. data/core/lib/topcoder/generate.rb +0 -131
  48. data/core/test/topcoder/generate_test.rb +0 -31
  49. data/core/test/topcoder/signature_test.rb +0 -52
  50. data/core/test/topcoder/types_test.rb +0 -24
  51. data/dist/template/solve/cpp/{name}Test.cpp +0 -8
  52. data/dist/template/solve/haskell/{name}Test.hs +0 -10
  53. data/dist/template/solve/java/{name}Test.java +0 -8
@@ -1,7 +1,7 @@
1
- require 'topcoder/problem'
2
- require 'rdiscount'
1
+ require "gettc/problem"
2
+ require "rdiscount"
3
3
 
4
- module TopCoder
4
+ module Gettc
5
5
  class Problem
6
6
  def to_md
7
7
  out = "# [#{@name}](#{@url})\n"
@@ -10,19 +10,19 @@ module TopCoder
10
10
  out << "## Statement\n"
11
11
  out << @statement << "\n\n"
12
12
 
13
- if not @definitions.empty? then
13
+ unless @definitions.empty? then
14
14
  out << "## Definitions\n"
15
15
  @definitions.each do |k, v| out << "- *#{k}*: `#{v}`\n" end
16
16
  out << "\n"
17
17
  end
18
18
 
19
- if not @notes.empty? then
19
+ unless @notes.empty? then
20
20
  out << "## Notes\n"
21
21
  @notes.each do |note| out << "- #{note}\n" end
22
22
  out << "\n"
23
23
  end
24
24
 
25
- if not @constraints.empty? then
25
+ unless @constraints.empty? then
26
26
  out << "## Constraints\n"
27
27
  @constraints.each do |constraint|
28
28
  out << "- #{constraint}\n"
@@ -30,18 +30,18 @@ module TopCoder
30
30
  out << "\n"
31
31
  end
32
32
 
33
- if not @examples.empty? then
33
+ unless @examples.empty? then
34
34
  out << "## Examples\n"
35
35
  @examples.each_index do |i|
36
36
  example = @examples[i]
37
37
  out << "### Example #{i + 1}\n"
38
38
  out << "#### Input\n<c>"
39
- out << example.input.gsub("\n", '<br />')
39
+ out << example.input.gsub("\n", "<br />")
40
40
  out << "</c>\n"
41
41
  out << "#### Output\n<c>"
42
- out << example.output.gsub("\n", '<br />')
42
+ out << example.output.gsub("\n", "<br />")
43
43
  out << "</c>\n"
44
- if not example.reason.empty? then
44
+ unless example.reason.empty? then
45
45
  out << "#### Reason\n#{example.reason}\n\n"
46
46
  end
47
47
  end
@@ -53,4 +53,4 @@ module TopCoder
53
53
  return markdown.to_html
54
54
  end
55
55
  end
56
- end
56
+ end
@@ -1,27 +1,27 @@
1
- module TopCoder
1
+ module Gettc
2
2
  class Case
3
3
  attr_accessor :input, :output, :reason
4
4
  def initialize
5
- @input = ''
6
- @output = ''
7
- @reason = ''
5
+ @input = ""
6
+ @output = ""
7
+ @reason = ""
8
8
  end
9
9
  end
10
10
  class Image
11
11
  attr_accessor :name, :content
12
12
  def initialize
13
- @name = ''
14
- @content = ''
13
+ @name = ""
14
+ @content = ""
15
15
  end
16
16
  end
17
17
  class Problem
18
18
  attr_accessor :name, :url, :source, :statement, :definitions, :notes,
19
19
  :constraints, :examples, :systests, :images
20
20
  def initialize
21
- @name = ''
22
- @url = ''
23
- @source = ''
24
- @statement = ''
21
+ @name = ""
22
+ @url = ""
23
+ @source = ""
24
+ @statement = ""
25
25
  @definitions = { }
26
26
  @notes = []
27
27
  @constraints = []
@@ -30,4 +30,4 @@ module TopCoder
30
30
  @images = []
31
31
  end
32
32
  end
33
- end
33
+ end
@@ -1,18 +1,18 @@
1
- require 'topcoder/types'
1
+ require "gettc/types"
2
2
 
3
- module TopCoder
3
+ module Gettc
4
4
  class SignatureError < StandardError
5
5
  end
6
6
  class CannotParseSignature < SignatureError
7
7
  attr_accessor :source
8
- def initialize source, msg = 'Cannot parse signature'
8
+ def initialize source, msg = "Cannot parse signature"
9
9
  @source = source
10
10
  super "#{msg} (#{source}"
11
11
  end
12
12
  end
13
13
  class InvalidVariableName < SignatureError
14
14
  attr_accessor :name
15
- def initialize name, msg = 'Invalid variable name'
15
+ def initialize name, msg = "Invalid variable name"
16
16
  @name = name
17
17
  super "#{msg} (#{name})"
18
18
  end
@@ -39,17 +39,17 @@ module TopCoder
39
39
  def parse_method_signature str
40
40
  str.strip!
41
41
  sigs = []
42
- parts = str.split '('
42
+ parts = str.split "("
43
43
  raise CannotParseSignature.new str if parts.size != 2
44
44
  sigs << parse_signature(parts[0])
45
45
 
46
46
  str = parts[1]
47
- raise CannotParseSignature.new str if str[-1] != ')'
47
+ raise CannotParseSignature.new str if str[-1] != ")"
48
48
  str.chop!
49
49
 
50
- parts = str.split ','
50
+ parts = str.split ","
51
51
  parts.each do |sig| sigs << parse_signature(sig) end
52
52
 
53
53
  return sigs
54
54
  end
55
- end
55
+ end
@@ -1,11 +1,8 @@
1
- require 'singleton'
2
-
3
- module TopCoder
4
- class TypeError < StandardError
5
- end
1
+ module Gettc
2
+ TypeError = Class.new StandardError
6
3
  class UnrecognizedType < TypeError
7
4
  attr_accessor :type
8
- def initialize type = nil, msg = 'Not a valid TopCoder type'
5
+ def initialize type = nil, msg = "Not a valid TopCoder type"
9
6
  @type = type
10
7
  super "#{msg} (#{type})"
11
8
  end
@@ -17,6 +14,26 @@ module TopCoder
17
14
  def obj?
18
15
  return @is_object
19
16
  end
17
+ def to_s
18
+ if self == TInt then
19
+ return "int"
20
+ elsif self == TLong then
21
+ return "long"
22
+ elsif self == TFloat then
23
+ return "float"
24
+ elsif self == TDouble then
25
+ return "double"
26
+ elsif self == TChar then
27
+ return "char"
28
+ elsif self == TString then
29
+ return "String"
30
+ elsif self == TBoolean then
31
+ return "boolean"
32
+ elsif is_a? TArray then
33
+ return subtype.to_s + "[]"
34
+ end
35
+ return "unknown"
36
+ end
20
37
  end
21
38
  TBoolean = Type.new false
22
39
  TInt = Type.new false
@@ -28,11 +45,11 @@ module TopCoder
28
45
  class TArray < Type
29
46
  attr_accessor :subtype
30
47
  def initialize subtype
31
- raise UnrecognizedType.new subtype if not subtype.is_a? Type
48
+ raise UnrecognizedType.new subtype unless subtype.is_a? Type
32
49
  @subtype = subtype
33
50
  end
34
51
  def == ary
35
- return false if not ary.is_a? TArray
52
+ return false unless ary.is_a? TArray
36
53
  return @subtype == ary.subtype
37
54
  end
38
55
  def obj?
@@ -40,23 +57,23 @@ module TopCoder
40
57
  end
41
58
  end
42
59
  def parse_type str
43
- return TArray.new parse_type str[0 .. -3] if str[-2 .. -1] == '[]'
60
+ return TArray.new parse_type str[0 .. -3] if str[-2 .. -1] == "[]"
44
61
  case str
45
- when 'boolean'
62
+ when "boolean"
46
63
  return TBoolean
47
- when 'int'
64
+ when "int"
48
65
  return TInt
49
- when 'long'
66
+ when "long"
50
67
  return TLong
51
- when 'float'
68
+ when "float"
52
69
  return TFloat
53
- when 'double'
70
+ when "double"
54
71
  return TDouble
55
- when 'char'
72
+ when "char"
56
73
  return TChar
57
- when 'String'
74
+ when "String"
58
75
  return TString
59
76
  end
60
77
  raise UnrecognizedType.new str
61
78
  end
62
- end
79
+ end
@@ -1,14 +1,14 @@
1
- require 'test/unit'
2
- require 'topcoder/download'
1
+ require "test/unit"
2
+ require "topcoder/download"
3
3
  include TopCoder
4
4
 
5
5
  class DownloadTest < Test::Unit::TestCase
6
6
  def setup
7
- @account = Account.new 'gettc', 'algorithm'
7
+ @account = Account.new "gettc", "algorithm"
8
8
  end
9
9
  def test_wrong_account
10
10
  assert_raises LoginFailed do
11
- Downloader.new Account.new 'username', 'password'
11
+ Downloader.new Account.new "username", "password"
12
12
  end
13
13
  end
14
14
  def test_wrong_id
@@ -23,7 +23,7 @@ class DownloadTest < Test::Unit::TestCase
23
23
  3.times do
24
24
  id = ids[rand ids.size]
25
25
  html = downloader.download_problem id
26
- assert_match '<h3>Problem Statement</h3>', html
26
+ assert_match "<h3>Problem Statement</h3>", html
27
27
  end
28
28
  end
29
- 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 unless 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 unless File.exists? prob_d
28
+ assert_raise ProblemDirExists do @generator.generate prob end
29
+ FileUtils.rmdir prob_d
30
+ end
31
+ end
@@ -1,34 +1,34 @@
1
- require 'test/unit'
2
- require 'topcoder/parse'
1
+ require "test/unit"
2
+ require "topcoder/parse"
3
3
  include TopCoder
4
4
 
5
5
  class ParseTest < Test::Unit::TestCase
6
6
  def setup
7
- downloader = Downloader.new Account.new 'gettc', 'algorithm'
7
+ downloader = Downloader.new Account.new "gettc", "algorithm"
8
8
  @parser = Parser.new downloader
9
- @datadir = File.join File.dirname(__FILE__), '../../files/stats'
9
+ @data_d = File.join File.dirname(__FILE__), "../../temp/download_problem_statement"
10
10
  end
11
11
  def get_problem_raw prob
12
- return File.read File.join @datadir, prob + '.htm'
12
+ return File.read File.join @data_d, prob + ".htm"
13
13
  end
14
14
  def test_indexes
15
- assert_equal [0, 3], @parser.indexes('abcde', 'bc')
16
- assert_equal nil, @parser.indexes('abcde', 'f')
15
+ assert_equal [0, 3], @parser.indexes("abcde", "bc")
16
+ assert_equal nil, @parser.indexes("abcde", "f")
17
17
  end
18
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>')
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
22
  html = <<-END
23
23
  <img src=
24
24
  "http://www.topcoder.com/contest/problem/CirclesCountry/case1.gif">
25
25
  END
26
- assert_equal '![image](images/case1.gif)', @parser.filter(html)
26
+ assert_equal "![image](images/case1.gif)", @parser.filter(html)
27
27
  end
28
28
  def test_PageNumbers
29
- html = get_problem_raw 'PageNumbers'
29
+ html = get_problem_raw "PageNumbers"
30
30
  prob = @parser.parse html
31
- assert_equal 'PageNumbers', prob.name
31
+ assert_equal "PageNumbers", prob.name
32
32
  assert_equal 5, prob.definitions.size
33
33
  assert_equal 1, prob.notes.size
34
34
  assert_equal 1, prob.constraints.size
@@ -37,9 +37,9 @@ class ParseTest < Test::Unit::TestCase
37
37
  assert_equal 0, prob.images.size
38
38
  end
39
39
  def test_CirclesCountry
40
- html = get_problem_raw 'CirclesCountry'
40
+ html = get_problem_raw "CirclesCountry"
41
41
  prob = @parser.parse html
42
- assert_equal 'CirclesCountry', prob.name
42
+ assert_equal "CirclesCountry", prob.name
43
43
  assert_equal 5, prob.definitions.size
44
44
  assert_equal 0, prob.notes.size
45
45
  assert_equal 7, prob.constraints.size
@@ -48,9 +48,9 @@ class ParseTest < Test::Unit::TestCase
48
48
  assert_equal 4, prob.images.size
49
49
  end
50
50
  def test_TheTournamentDivOne
51
- html = get_problem_raw 'TheTournamentDivOne'
51
+ html = get_problem_raw "TheTournamentDivOne"
52
52
  prob = @parser.parse html
53
- assert_equal 'TheTournamentDivOne', prob.name
53
+ assert_equal "TheTournamentDivOne", prob.name
54
54
  assert_equal 5, prob.definitions.size
55
55
  assert_equal 0, prob.notes.size
56
56
  assert_equal 4, prob.constraints.size
@@ -59,9 +59,9 @@ class ParseTest < Test::Unit::TestCase
59
59
  assert_equal 0, prob.images.size
60
60
  end
61
61
  def test_FunnyGames
62
- html = get_problem_raw 'FunnyGames'
62
+ html = get_problem_raw "FunnyGames"
63
63
  prob = @parser.parse html
64
- assert_equal 'FunnyGames', prob.name
64
+ assert_equal "FunnyGames", prob.name
65
65
  assert_equal 5, prob.definitions.size
66
66
  assert_equal 0, prob.notes.size
67
67
  assert_equal 6, prob.constraints.size
@@ -70,9 +70,9 @@ class ParseTest < Test::Unit::TestCase
70
70
  assert_equal 0, prob.images.size
71
71
  end
72
72
  def test_BuildingRoads
73
- html = get_problem_raw 'BuildingRoads'
73
+ html = get_problem_raw "BuildingRoads"
74
74
  prob = @parser.parse html
75
- assert_equal 'BuildingRoads', prob.name
75
+ assert_equal "BuildingRoads", prob.name
76
76
  assert_equal 5, prob.definitions.size
77
77
  assert_equal 2, prob.notes.size
78
78
  assert_equal 10, prob.constraints.size
@@ -81,9 +81,9 @@ class ParseTest < Test::Unit::TestCase
81
81
  assert_equal 2, prob.images.size
82
82
  end
83
83
  def test_Acronyms
84
- html = get_problem_raw 'Acronyms'
84
+ html = get_problem_raw "Acronyms"
85
85
  prob = @parser.parse html
86
- assert_equal 'Acronyms', prob.name
86
+ assert_equal "Acronyms", prob.name
87
87
  assert_equal 5, prob.definitions.size
88
88
  assert_equal 1, prob.notes.size
89
89
  assert_equal 8, prob.constraints.size
@@ -92,13 +92,13 @@ class ParseTest < Test::Unit::TestCase
92
92
  assert_equal 0, prob.images.size
93
93
  end
94
94
  def test_BackyardTrees
95
- html = get_problem_raw 'BackyardTrees'
95
+ html = get_problem_raw "BackyardTrees"
96
96
  prob = @parser.parse html
97
- assert_equal 'BackyardTrees', prob.name
97
+ assert_equal "BackyardTrees", prob.name
98
98
  assert_equal 5, prob.definitions.size
99
99
  assert_equal 0, prob.notes.size
100
100
  assert_equal 4, prob.constraints.size
101
101
  assert_equal 6, prob.examples.size
102
102
  assert_equal 2, prob.images.size
103
103
  end
104
- end
104
+ end
@@ -0,0 +1,54 @@
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
17
+ parse_signature "int 0zero"
18
+ end
19
+ sig = parse_signature "String[] a_valid_nam3"
20
+ assert_equal TArray.new(TString), sig.type
21
+ assert_equal "a_valid_nam3", sig.name
22
+ end
23
+ def test_parse_method_signature
24
+ assert_raise CannotParseSignature do
25
+ parse_method_signature "there are no brackets"
26
+ end
27
+ assert_raise CannotParseSignature do
28
+ parse_method_signature "int main(int main())"
29
+ end
30
+ assert_raise CannotParseSignature do
31
+ parse_method_signature "int main(oops forget to close bracket"
32
+ end
33
+ method = " int leastBorders(String[] X , int[] Y, double[] R,"
34
+ method += " char my_x1, long y1 , float x2, int[][] y2) "
35
+ sigs = parse_method_signature method
36
+ assert_equal 8, sigs.size
37
+ assert_equal TInt, sigs[0].type
38
+ assert_equal "leastBorders", sigs[0].name
39
+ assert_equal TArray.new(TString), sigs[1].type
40
+ assert_equal "X", sigs[1].name
41
+ assert_equal TArray.new(TInt), sigs[2].type
42
+ assert_equal "Y", sigs[2].name
43
+ assert_equal TArray.new(TDouble), sigs[3].type
44
+ assert_equal "R", sigs[3].name
45
+ assert_equal TChar, sigs[4].type
46
+ assert_equal "my_x1", sigs[4].name
47
+ assert_equal TLong, sigs[5].type
48
+ assert_equal "y1", sigs[5].name
49
+ assert_equal TFloat, sigs[6].type
50
+ assert_equal "x2", sigs[6].name
51
+ assert_equal TArray.new(TArray.new(TInt)), sigs[7].type
52
+ assert_equal "y2", sigs[7].name
53
+ end
54
+ end