atcoder_greedy 0.1.1 → 0.2.0
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 +4 -4
- data/README.md +40 -32
- data/lib/atcoder_greedy/command/create.rb +21 -26
- data/lib/atcoder_greedy/command/test.rb +84 -0
- data/lib/atcoder_greedy/command.rb +2 -1
- data/lib/atcoder_greedy/templates/ruby/solve.rb +2 -22
- data/lib/atcoder_greedy/version.rb +1 -1
- metadata +3 -3
- data/lib/atcoder_greedy/templates/ruby/test.rb +0 -61
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02ce08f02c28c663958ba6d89dcac332515dce41
|
4
|
+
data.tar.gz: e685ca727b9bddf4d8ba65172b2ec56e8ccd3d36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 18d4b206ee22ea32e6d91f31d2c276d6b4f186714856b33b9a9980461eb8efa7beead044d553a1970bd97111aa645b9469dc1868dc3c2ff3a851240c5144e765
|
7
|
+
data.tar.gz: dccb6400815a5ed90d6da2c5bc4140c39c1e5998d4b888bbc43b20e8ea86fb129c31bb5f22aed638eff3987284d1fdb5cd5345b00ce7769215c69c669034e1aa
|
data/README.md
CHANGED
@@ -7,63 +7,71 @@
|
|
7
7
|
|
8
8
|
## Usage
|
9
9
|
|
10
|
+
### テンプレートファイルの作成
|
10
11
|
```
|
12
|
+
# create contest templates
|
11
13
|
$ atcoder_greedy create CONTESTNAME
|
12
14
|
```
|
13
15
|
|
14
|
-
|
16
|
+
### テストの実行
|
17
|
+
```
|
18
|
+
$ cd CONTESTNAME
|
19
|
+
$ atcoder_greedy test PROBLEMNAME
|
20
|
+
```
|
21
|
+
|
22
|
+
## 使用例
|
23
|
+
ABC009の場合
|
15
24
|
|
16
25
|
```
|
17
|
-
$ atcoder_greedy create
|
26
|
+
$ atcoder_greedy create abc009
|
18
27
|
```
|
19
28
|
|
20
29
|
とすると、以下のようなファイルが生成される。
|
21
30
|
|
22
31
|
```
|
23
32
|
.
|
24
|
-
├──
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
├──
|
30
|
-
|
31
|
-
|
32
|
-
│ ├── output.txt
|
33
|
-
│ └── test_abc008_2.rb
|
34
|
-
├── abc008_3
|
35
|
-
│ ├── abc008_3.rb
|
36
|
-
│ ├── input.txt
|
37
|
-
│ ├── output.txt
|
38
|
-
│ └── test_abc008_3.rb
|
39
|
-
└── abc008_4
|
40
|
-
├── abc008_4.rb
|
41
|
-
├── input.txt
|
42
|
-
├── output.txt
|
43
|
-
└── test_abc008_4.rb
|
33
|
+
├── A.rb
|
34
|
+
├── B.rb
|
35
|
+
├── C.rb
|
36
|
+
├── D.rb
|
37
|
+
├── input_A.txt
|
38
|
+
├── input_B.txt
|
39
|
+
├── input_C.txt
|
40
|
+
└── input_D.txt
|
44
41
|
```
|
45
42
|
|
46
|
-
各問題について,
|
43
|
+
各問題について,X.rbに自分の解答を記述すれば良い。
|
44
|
+
input_X.txtにはX.rbのサンプルインプット,アウトプットが記載されている.
|
47
45
|
|
48
|
-
|
49
|
-
|
50
|
-
テストを実行するには、
|
46
|
+
A問題についてテストを実行するには、
|
51
47
|
|
52
48
|
```
|
53
|
-
$
|
54
|
-
$ ruby test_abc00X_Y.rb
|
49
|
+
$ atcoder_greedy test A.rb
|
55
50
|
```
|
56
51
|
|
57
|
-
|
52
|
+
とすると、以下のようにテスト結果が表示される。
|
53
|
+
|
54
|
+
```
|
55
|
+
Running a test for problem A...
|
56
|
+
Testcase #0 ... PASSED! Time: 0.04137948894640431s
|
57
|
+
Testcase #1 ... FAILED! Time: 0.051738745998591185s
|
58
|
+
Your Output:
|
59
|
+
3
|
60
|
+
|
61
|
+
Correct Answer:
|
62
|
+
2
|
63
|
+
|
64
|
+
Testcase #2 ... PASSED! Time: 0.05054747499525547s
|
65
|
+
Test done.
|
66
|
+
```
|
58
67
|
|
59
68
|
## 実装した機能
|
69
|
+
- 解答ファイルのテンプレート生成
|
60
70
|
- サンプルインプット、アウトプットを用いたテストファイルの生成
|
61
|
-
-
|
71
|
+
- テスト実行コマンド
|
62
72
|
|
63
73
|
|
64
74
|
## TODO,実装したい機能
|
65
|
-
- リファクタリング
|
66
|
-
- テスト結果を見やすく
|
67
75
|
- 問題を指定してその問題のみ生成
|
68
76
|
- 提出機能
|
69
77
|
- 多言語もテンプレートから生成したい
|
@@ -4,17 +4,19 @@ require 'atcoder_greedy/command'
|
|
4
4
|
module AtcoderGreedy
|
5
5
|
class Command < Thor
|
6
6
|
desc 'create CONTESTNAME', 'create contest templates for CONTESTNAME'
|
7
|
+
|
7
8
|
def create(contest_name)
|
8
9
|
Contest.new(contest_name.downcase)
|
9
10
|
end
|
10
11
|
end
|
11
12
|
|
12
13
|
TEMPLATE_PATH = File.join(File.dirname(__dir__), '/templates')
|
13
|
-
TEST_TEMPLATE = open(TEMPLATE_PATH + '/ruby/test.rb', &:read)
|
14
14
|
SOLVE_TEMPLATE = open(TEMPLATE_PATH + '/ruby/solve.rb', &:read)
|
15
|
+
PROBLEM_NAMES = %w(A B C D)
|
15
16
|
|
16
17
|
class Contest
|
17
18
|
attr_accessor :name, :url
|
19
|
+
|
18
20
|
def initialize(name)
|
19
21
|
@name = name
|
20
22
|
puts "Create #{name} contest files"
|
@@ -23,6 +25,7 @@ module AtcoderGreedy
|
|
23
25
|
@problem_urls = create_contest_problem_urls(name)
|
24
26
|
puts 'Create directories'
|
25
27
|
create_directories
|
28
|
+
create_templates
|
26
29
|
puts 'Set up done.'
|
27
30
|
end
|
28
31
|
|
@@ -40,16 +43,14 @@ module AtcoderGreedy
|
|
40
43
|
end
|
41
44
|
|
42
45
|
4.times do |i|
|
43
|
-
urls.push(name: "#{
|
46
|
+
urls.push(name: "#{PROBLEM_NAMES[i]}", path: @base_url + "/tasks/#{contest_name}_#{task_num[i]}")
|
44
47
|
end
|
45
48
|
urls
|
46
49
|
end
|
47
50
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
@problem_urls.each do |url|
|
51
|
+
def create_templates
|
52
|
+
@problem_urls.each_with_index do |url, pro_i|
|
53
|
+
problem_dir = "./#{@name}"
|
53
54
|
# urlからインプット、アウトプットパラメータをとってきてファイルにしまう
|
54
55
|
charset = nil
|
55
56
|
html = open(url[:path]) do |f|
|
@@ -57,40 +58,34 @@ module AtcoderGreedy
|
|
57
58
|
f.read
|
58
59
|
end
|
59
60
|
doc = Nokogiri::HTML.parse(html, nil, charset)
|
60
|
-
|
61
|
-
problem_dir = "./#{@name}/#{url[:name]}"
|
62
|
-
FileUtils.mkdir(problem_dir)
|
63
|
-
|
64
|
-
in_file = File.new(problem_dir + '/input.txt', 'w')
|
65
|
-
out_file = File.new(problem_dir + '/output.txt', 'w')
|
61
|
+
in_file = File.new(problem_dir + "/input_#{PROBLEM_NAMES[pro_i]}.txt", 'w')
|
66
62
|
|
67
63
|
params = doc.xpath('//pre')
|
68
64
|
params.shift
|
69
65
|
params.each_with_index do |p, i|
|
70
66
|
if i % 2 == 0
|
71
|
-
in_file.
|
67
|
+
in_file.puts "-- Example #{i/2}"
|
68
|
+
in_file.puts "#{p.text.gsub(/\r\n?/, "\n").strip}"
|
72
69
|
else
|
73
|
-
|
70
|
+
in_file.puts "-- Answer #{(i-1)/2}"
|
71
|
+
in_file.puts "#{p.text.gsub(/\r\n?/, "\n").strip}"
|
74
72
|
end
|
75
73
|
end
|
76
74
|
|
77
75
|
in_file.close
|
78
|
-
out_file.close
|
79
|
-
|
80
|
-
# テストファイル,解答ファイルの生成
|
81
|
-
test_file_content = TEST_TEMPLATE.clone
|
82
|
-
test_file_content.gsub!(/NAME/, url[:name].capitalize)
|
83
|
-
test_file_content.gsub!(/PROBLEM/, url[:name])
|
84
|
-
test_file = File.new(problem_dir + "/test_#{url[:name]}.rb", 'w')
|
85
|
-
test_file.print test_file_content
|
86
|
-
test_file.close
|
87
76
|
|
88
77
|
solve_file_content = SOLVE_TEMPLATE.clone
|
89
|
-
solve_file_content.gsub!(/
|
78
|
+
solve_file_content.gsub!(/CONTEST/, @name.upcase)
|
79
|
+
solve_file_content.gsub!(/PROBLEM/, url[:name].upcase)
|
90
80
|
solve_file = File.new(problem_dir + "/#{url[:name]}.rb", 'w')
|
91
81
|
solve_file.print solve_file_content
|
92
82
|
solve_file.close
|
93
83
|
end
|
94
84
|
end
|
85
|
+
|
86
|
+
def create_directories
|
87
|
+
# コンテストディレクトリ作成
|
88
|
+
FileUtils.mkdir(@name)
|
89
|
+
end
|
95
90
|
end
|
96
|
-
end
|
91
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'atcoder_greedy'
|
2
|
+
require 'atcoder_greedy/command'
|
3
|
+
require 'diff/lcs'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'benchmark'
|
6
|
+
|
7
|
+
|
8
|
+
module AtcoderGreedy
|
9
|
+
class Command < Thor
|
10
|
+
desc 'test PROBLEMNAME', 'test your solution'
|
11
|
+
|
12
|
+
def test(problem_name)
|
13
|
+
name = File.basename(problem_name, '.*')
|
14
|
+
puts "Running a test for problem #{name}..."
|
15
|
+
TestCase.new(name).validate
|
16
|
+
puts "Test done."
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class TestCase
|
21
|
+
def initialize(problem_name)
|
22
|
+
@input_file = File.open("./input_#{problem_name}.txt", 'r')
|
23
|
+
@exec_file = "./#{problem_name}.rb"
|
24
|
+
get_in_out
|
25
|
+
end
|
26
|
+
|
27
|
+
def get_in_out
|
28
|
+
i = 0
|
29
|
+
@input = []
|
30
|
+
@output = []
|
31
|
+
now = nil
|
32
|
+
while (t = @input_file.gets) != nil
|
33
|
+
example_string = "-- Example #{i}"
|
34
|
+
answer_string = "-- Answer #{i}"
|
35
|
+
|
36
|
+
if t.chomp == example_string
|
37
|
+
now.close(false) unless now.nil?
|
38
|
+
now = Tempfile.new(['in', '.txt'], './')
|
39
|
+
@input.push(now)
|
40
|
+
now.open
|
41
|
+
elsif t.chomp == answer_string
|
42
|
+
now.close(false) unless now.nil?
|
43
|
+
now = Tempfile.new(['out', '.txt'], './')
|
44
|
+
@output.push(now)
|
45
|
+
now.open
|
46
|
+
i += 1
|
47
|
+
else
|
48
|
+
now.puts t
|
49
|
+
end
|
50
|
+
end
|
51
|
+
@input[-1].close(false)
|
52
|
+
@output[-1].close(false)
|
53
|
+
end
|
54
|
+
|
55
|
+
def validate
|
56
|
+
@input.size.times do |j|
|
57
|
+
myout_file = Tempfile.new(['myout', '.txt'], './')
|
58
|
+
myout_file.open
|
59
|
+
result = Benchmark.realtime do
|
60
|
+
pid = Process.fork do
|
61
|
+
exec "ruby #{@exec_file} < #{@input[j].path} > #{myout_file.path}"
|
62
|
+
@input[j].close
|
63
|
+
myout_file.close(false)
|
64
|
+
end
|
65
|
+
Process.waitpid pid
|
66
|
+
end
|
67
|
+
|
68
|
+
myout = myout_file.open.read
|
69
|
+
myout_file.close
|
70
|
+
correct = File.open("#{@output[j].path}").read
|
71
|
+
diffs = Diff::LCS.diff(myout, correct)
|
72
|
+
if diffs.size == 0
|
73
|
+
puts "Testcase ##{j} ... PASSED! Time: #{result}s"
|
74
|
+
else
|
75
|
+
puts "Testcase ##{j} ... FAILED! Time: #{result}s"
|
76
|
+
puts "Your Output:"
|
77
|
+
puts "#{myout}\n"
|
78
|
+
puts "Correct Answer:"
|
79
|
+
puts "#{correct}\n"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -1,22 +1,2 @@
|
|
1
|
-
#
|
2
|
-
|
3
|
-
|
4
|
-
class NAME
|
5
|
-
alias :puts_original :puts
|
6
|
-
def initialize(input)
|
7
|
-
@f = StringIO.new(input)
|
8
|
-
end
|
9
|
-
|
10
|
-
def gets
|
11
|
-
@f.gets
|
12
|
-
end
|
13
|
-
|
14
|
-
def puts(a)
|
15
|
-
puts_original a
|
16
|
-
a
|
17
|
-
end
|
18
|
-
|
19
|
-
def solve
|
20
|
-
# write your program here
|
21
|
-
end
|
22
|
-
end
|
1
|
+
# CONTEST PROBLEM
|
2
|
+
# Your code here
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: atcoder_greedy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- keigo-brook
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-01-
|
11
|
+
date: 2016-01-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -104,8 +104,8 @@ files:
|
|
104
104
|
- lib/atcoder_greedy.rb
|
105
105
|
- lib/atcoder_greedy/command.rb
|
106
106
|
- lib/atcoder_greedy/command/create.rb
|
107
|
+
- lib/atcoder_greedy/command/test.rb
|
107
108
|
- lib/atcoder_greedy/templates/ruby/solve.rb
|
108
|
-
- lib/atcoder_greedy/templates/ruby/test.rb
|
109
109
|
- lib/atcoder_greedy/version.rb
|
110
110
|
homepage: https://github.com/keigo-brook/atcoder_greedy
|
111
111
|
licenses:
|
@@ -1,61 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
require 'test/unit'
|
3
|
-
require_relative 'PROBLEM.rb'
|
4
|
-
|
5
|
-
class Test_NAME < Test::Unit::TestCase
|
6
|
-
def setup
|
7
|
-
@test_cases = create_test_cases
|
8
|
-
@sample_outputs = get_outputs
|
9
|
-
end
|
10
|
-
|
11
|
-
def create_test_cases
|
12
|
-
test_cases = []
|
13
|
-
in_file = File.open('./input.txt', 'r+:utf-8')
|
14
|
-
loop do
|
15
|
-
s = ''
|
16
|
-
loop do
|
17
|
-
t = in_file.gets
|
18
|
-
if t != nil && t.chomp.length > 0
|
19
|
-
s += t
|
20
|
-
else
|
21
|
-
break
|
22
|
-
end
|
23
|
-
end
|
24
|
-
if s.length == 0 && test_cases.size > 0
|
25
|
-
break
|
26
|
-
elsif s.length > 0
|
27
|
-
test_case = NAME.new(s)
|
28
|
-
test_cases.push(test_case)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
test_cases
|
32
|
-
end
|
33
|
-
|
34
|
-
def get_outputs
|
35
|
-
outputs = []
|
36
|
-
out_file = File.open('./output.txt', 'r+:utf-8')
|
37
|
-
loop do
|
38
|
-
s = ''
|
39
|
-
loop do
|
40
|
-
t = out_file.gets
|
41
|
-
if t != nil && t.chomp.length > 0
|
42
|
-
s += t
|
43
|
-
else
|
44
|
-
break
|
45
|
-
end
|
46
|
-
end
|
47
|
-
if s.length == 0 && outputs.size > 0
|
48
|
-
break
|
49
|
-
elsif s.length > 0
|
50
|
-
outputs.push(s.chomp)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
outputs
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_PROBLEM
|
57
|
-
@test_cases.each_with_index do |obj, i|
|
58
|
-
assert_equal(@sample_outputs[i], obj.solve.to_s)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|