gettc 1.5 → 1.6

Sign up to get free protection for your applications and to get access to all the features.
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