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