at_coder_friends 0.6.3 → 0.6.4
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/.travis.yml +1 -1
- data/CHANGELOG.md +3 -0
- data/Gemfile.lock +12 -12
- data/at_coder_friends.gemspec +1 -1
- data/lib/at_coder_friends/cli.rb +1 -1
- data/lib/at_coder_friends/config_loader.rb +11 -3
- data/lib/at_coder_friends/context.rb +10 -6
- data/lib/at_coder_friends/emitter.rb +2 -2
- data/lib/at_coder_friends/generator/base.rb +2 -1
- data/lib/at_coder_friends/parser/modulo.rb +1 -1
- data/lib/at_coder_friends/path_info.rb +51 -0
- data/lib/at_coder_friends/path_util.rb +0 -31
- data/lib/at_coder_friends/scraping/agent.rb +1 -2
- data/lib/at_coder_friends/scraping/custom_test.rb +1 -3
- data/lib/at_coder_friends/scraping/submission.rb +1 -3
- data/lib/at_coder_friends/test_runner/base.rb +17 -4
- data/lib/at_coder_friends/test_runner/judge.rb +7 -9
- data/lib/at_coder_friends/test_runner/sample.rb +2 -4
- data/lib/at_coder_friends/verifier.rb +2 -3
- data/lib/at_coder_friends/version.rb +1 -1
- data/lib/at_coder_friends.rb +1 -0
- data/templates/cxx_builtin.cxx.erb +21 -17
- data/templates/ruby_builtin.rb.erb +11 -10
- metadata +3 -11
- data/tasks/regression/check_const.rake +0 -137
- data/tasks/regression/check_diff.rake +0 -30
- data/tasks/regression/check_fmt.rake +0 -45
- data/tasks/regression/check_parse.rake +0 -69
- data/tasks/regression/list_handler.rb +0 -46
- data/tasks/regression/regression.rb +0 -38
- data/tasks/regression/report_handler.rb +0 -20
- data/tasks/regression/section_list.rake +0 -53
- data/tasks/regression/setup.rake +0 -48
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac22f93d26dc92de38a01ed67b2fa1a8465380c2
|
4
|
+
data.tar.gz: 28e89a872bcc0825b5a4f53019fd43a7dea07511
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dee4b060fbd70915fa8e59c170a9d02e9d2ae8af925251d89e4fb3f5b1a9d7d33e20f71ffb39de4ea54190ff50011ac0ad8795149c576134a12f876448831cf8
|
7
|
+
data.tar.gz: 02a32cd3a62047c90cd8dd30269a8d5d6c82d443bc1f7e7adebfddc4c78742a6d4bd3ff6f53a24ec71f10da5bdd74a34ce9107cd7463d6b1b575adc317714bf5
|
data/.travis.yml
CHANGED
@@ -7,7 +7,7 @@ env:
|
|
7
7
|
- CC_TEST_REPORTER_ID=cb942bcc168feb78c43c506364d5344c5ec9a46a0b68dc66acb581e77c981ff1
|
8
8
|
- COVERAGE=true
|
9
9
|
before_install:
|
10
|
-
- gem install bundler -v '2.
|
10
|
+
- gem install bundler -v '2.1.4'
|
11
11
|
before_script:
|
12
12
|
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
13
13
|
- chmod +x ./cc-test-reporter
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
at_coder_friends (0.6.
|
4
|
+
at_coder_friends (0.6.4)
|
5
5
|
colorize (~> 0.8.1)
|
6
6
|
launchy (~> 2.4.3)
|
7
7
|
mechanize (~> 2.0)
|
@@ -19,10 +19,10 @@ GEM
|
|
19
19
|
docile (1.3.2)
|
20
20
|
domain_name (0.5.20190701)
|
21
21
|
unf (>= 0.0.5, < 1.0.0)
|
22
|
-
hashdiff (1.0.
|
22
|
+
hashdiff (1.0.1)
|
23
23
|
http-cookie (1.0.3)
|
24
24
|
domain_name (~> 0.5)
|
25
|
-
json (2.
|
25
|
+
json (2.3.0)
|
26
26
|
launchy (2.4.3)
|
27
27
|
addressable (~> 2.3)
|
28
28
|
mechanize (2.7.6)
|
@@ -34,31 +34,31 @@ GEM
|
|
34
34
|
nokogiri (~> 1.6)
|
35
35
|
ntlm-http (~> 0.1, >= 0.1.1)
|
36
36
|
webrobots (>= 0.0.9, < 0.2)
|
37
|
-
mime-types (3.3)
|
37
|
+
mime-types (3.3.1)
|
38
38
|
mime-types-data (~> 3.2015)
|
39
39
|
mime-types-data (3.2019.1009)
|
40
40
|
mini_portile2 (2.4.0)
|
41
41
|
net-http-digest_auth (1.4.1)
|
42
42
|
net-http-persistent (3.1.0)
|
43
43
|
connection_pool (~> 2.2)
|
44
|
-
nokogiri (1.10.
|
44
|
+
nokogiri (1.10.9)
|
45
45
|
mini_portile2 (~> 2.4.0)
|
46
46
|
ntlm-http (0.1.1)
|
47
|
-
public_suffix (4.0.
|
47
|
+
public_suffix (4.0.3)
|
48
48
|
rake (13.0.1)
|
49
49
|
rspec (3.9.0)
|
50
50
|
rspec-core (~> 3.9.0)
|
51
51
|
rspec-expectations (~> 3.9.0)
|
52
52
|
rspec-mocks (~> 3.9.0)
|
53
|
-
rspec-core (3.9.
|
54
|
-
rspec-support (~> 3.9.
|
53
|
+
rspec-core (3.9.1)
|
54
|
+
rspec-support (~> 3.9.1)
|
55
55
|
rspec-expectations (3.9.0)
|
56
56
|
diff-lcs (>= 1.2.0, < 2.0)
|
57
57
|
rspec-support (~> 3.9.0)
|
58
|
-
rspec-mocks (3.9.
|
58
|
+
rspec-mocks (3.9.1)
|
59
59
|
diff-lcs (>= 1.2.0, < 2.0)
|
60
60
|
rspec-support (~> 3.9.0)
|
61
|
-
rspec-support (3.9.
|
61
|
+
rspec-support (3.9.2)
|
62
62
|
safe_yaml (1.0.5)
|
63
63
|
simplecov (0.17.1)
|
64
64
|
docile (~> 1.1)
|
@@ -68,7 +68,7 @@ GEM
|
|
68
68
|
unf (0.1.4)
|
69
69
|
unf_ext
|
70
70
|
unf_ext (0.0.7.6)
|
71
|
-
webmock (3.
|
71
|
+
webmock (3.8.2)
|
72
72
|
addressable (>= 2.3.6)
|
73
73
|
crack (>= 0.3.2)
|
74
74
|
hashdiff (>= 0.4.0, < 2.0.0)
|
@@ -87,4 +87,4 @@ DEPENDENCIES
|
|
87
87
|
webmock (~> 3.0)
|
88
88
|
|
89
89
|
BUNDLED WITH
|
90
|
-
2.
|
90
|
+
2.1.4
|
data/at_coder_friends.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
|
24
24
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
25
25
|
`git ls-files -z`.split("\x0").reject do |f|
|
26
|
-
f.match(%r{^(test|spec|features)/})
|
26
|
+
f.match(%r{^(test|spec|features|tasks)/})
|
27
27
|
end
|
28
28
|
end
|
29
29
|
spec.bindir = 'exe'
|
data/lib/at_coder_friends/cli.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'optparse'
|
4
|
-
require 'launchy'
|
5
4
|
|
6
5
|
module AtCoderFriends
|
7
6
|
# command line interface
|
@@ -140,6 +139,7 @@ module AtCoderFriends
|
|
140
139
|
end
|
141
140
|
|
142
141
|
def open_contest
|
142
|
+
require 'launchy'
|
143
143
|
Launchy.open(ctx.scraping_agent.contest_url)
|
144
144
|
end
|
145
145
|
end
|
@@ -11,20 +11,28 @@ module AtCoderFriends
|
|
11
11
|
DEFAULT_FILE = File.join(ACF_HOME, 'config', 'default.yml')
|
12
12
|
|
13
13
|
class << self
|
14
|
+
def dotfile
|
15
|
+
DOTFILE
|
16
|
+
end
|
17
|
+
|
18
|
+
def default_file
|
19
|
+
DEFAULT_FILE
|
20
|
+
end
|
21
|
+
|
14
22
|
def load_config(ctx)
|
15
23
|
path = config_file_for(ctx.path)
|
16
24
|
config = load_yaml(path)
|
17
|
-
return config if path ==
|
25
|
+
return config if path == default_file
|
18
26
|
|
19
27
|
merge_with_default(config)
|
20
28
|
end
|
21
29
|
|
22
30
|
def config_file_for(target_dir)
|
23
|
-
find_project_dotfile(target_dir) ||
|
31
|
+
find_project_dotfile(target_dir) || default_file
|
24
32
|
end
|
25
33
|
|
26
34
|
def find_project_dotfile(target_dir)
|
27
|
-
find_file_upwards(
|
35
|
+
find_file_upwards(dotfile, target_dir)
|
28
36
|
end
|
29
37
|
|
30
38
|
def find_file_upwards(filename, start_dir)
|
@@ -7,11 +7,15 @@ module AtCoderFriends
|
|
7
7
|
# - configuration
|
8
8
|
# - application modules
|
9
9
|
class Context
|
10
|
-
attr_reader :options, :
|
10
|
+
attr_reader :options, :path_info
|
11
11
|
|
12
12
|
def initialize(options, path)
|
13
13
|
@options = options
|
14
|
-
@
|
14
|
+
@path_info = PathInfo.new(File.expand_path(path))
|
15
|
+
end
|
16
|
+
|
17
|
+
def path
|
18
|
+
path_info.path
|
15
19
|
end
|
16
20
|
|
17
21
|
def config
|
@@ -26,6 +30,10 @@ module AtCoderFriends
|
|
26
30
|
@generator ||= Generator::Main.new(self)
|
27
31
|
end
|
28
32
|
|
33
|
+
def emitter
|
34
|
+
@emitter ||= Emitter.new(self)
|
35
|
+
end
|
36
|
+
|
29
37
|
def sample_test_runner
|
30
38
|
@sample_test_runner ||= TestRunner::Sample.new(self)
|
31
39
|
end
|
@@ -38,10 +46,6 @@ module AtCoderFriends
|
|
38
46
|
@verifier ||= Verifier.new(self)
|
39
47
|
end
|
40
48
|
|
41
|
-
def emitter
|
42
|
-
@emitter ||= Emitter.new(self)
|
43
|
-
end
|
44
|
-
|
45
49
|
def post_process
|
46
50
|
@scraping_agent&.save_session
|
47
51
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module AtCoderFriends
|
4
|
+
# holds target path information
|
5
|
+
class PathInfo
|
6
|
+
SMP_DIR = 'data'
|
7
|
+
CASES_DIR = 'cases'
|
8
|
+
TMP_DIR = '.tmp'
|
9
|
+
|
10
|
+
attr_reader :path, :dir
|
11
|
+
|
12
|
+
def initialize(path)
|
13
|
+
@path = path
|
14
|
+
# in setup command, path is directory name (existent/non-existent)
|
15
|
+
# in other commands(test, submit, verify), path is existent file name
|
16
|
+
@dir = File.file?(path) ? File.dirname(path) : path
|
17
|
+
end
|
18
|
+
|
19
|
+
def contest_name
|
20
|
+
File.basename(dir).delete('#').downcase
|
21
|
+
end
|
22
|
+
|
23
|
+
def components
|
24
|
+
# overwrites @dir here for non-existent files (test purpose)
|
25
|
+
@dir, prg = File.split(path)
|
26
|
+
base, ext = prg.split('.')
|
27
|
+
q = base.gsub(/_[^#_]+\z/, '')
|
28
|
+
[path, dir, prg, base, ext, q]
|
29
|
+
end
|
30
|
+
|
31
|
+
def src_dir
|
32
|
+
dir
|
33
|
+
end
|
34
|
+
|
35
|
+
def smp_dir
|
36
|
+
File.join(dir, SMP_DIR)
|
37
|
+
end
|
38
|
+
|
39
|
+
def cases_dir
|
40
|
+
File.join(dir, CASES_DIR)
|
41
|
+
end
|
42
|
+
|
43
|
+
def cases_out_dir
|
44
|
+
File.join(dir, TMP_DIR, CASES_DIR)
|
45
|
+
end
|
46
|
+
|
47
|
+
def tmp_dir
|
48
|
+
File.join(dir, TMP_DIR)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -3,37 +3,6 @@
|
|
3
3
|
module AtCoderFriends
|
4
4
|
# Common methods and behaviors for dealing with paths.
|
5
5
|
module PathUtil
|
6
|
-
module_function
|
7
|
-
|
8
|
-
SMP_DIR = 'data'
|
9
|
-
CASES_DIR = 'cases'
|
10
|
-
TMP_DIR = '.tmp'
|
11
|
-
|
12
|
-
def contest_name(path)
|
13
|
-
dir = File.file?(path) ? File.dirname(path) : path
|
14
|
-
File.basename(dir).delete('#').downcase
|
15
|
-
end
|
16
|
-
|
17
|
-
def split_prg_path(path)
|
18
|
-
dir, prg = File.split(path)
|
19
|
-
base, ext = prg.split('.')
|
20
|
-
q = base.split('_')[0]
|
21
|
-
[path, dir, prg, base, ext, q]
|
22
|
-
end
|
23
|
-
|
24
|
-
def smp_dir(dir)
|
25
|
-
File.join(dir, SMP_DIR)
|
26
|
-
end
|
27
|
-
|
28
|
-
def cases_dir(dir)
|
29
|
-
File.join(dir, CASES_DIR)
|
30
|
-
end
|
31
|
-
|
32
|
-
def tmp_dir(path)
|
33
|
-
dir = File.dirname(path)
|
34
|
-
File.join(dir, '.tmp')
|
35
|
-
end
|
36
|
-
|
37
6
|
def makedirs_unless(dir)
|
38
7
|
FileUtils.makedirs(dir) unless Dir.exist?(dir)
|
39
8
|
end
|
@@ -7,7 +7,6 @@ module AtCoderFriends
|
|
7
7
|
module Scraping
|
8
8
|
# common functions for scraping
|
9
9
|
class Agent
|
10
|
-
include AtCoderFriends::PathUtil
|
11
10
|
include Session
|
12
11
|
include Authentication
|
13
12
|
include Tasks
|
@@ -29,7 +28,7 @@ module AtCoderFriends
|
|
29
28
|
end
|
30
29
|
|
31
30
|
def contest
|
32
|
-
@contest ||=
|
31
|
+
@contest ||= ctx.path_info.contest_name
|
33
32
|
end
|
34
33
|
|
35
34
|
def common_url(path)
|
@@ -6,10 +6,8 @@ module AtCoderFriends
|
|
6
6
|
module Scraping
|
7
7
|
# run tests on custom_test page
|
8
8
|
module CustomTest
|
9
|
-
include AtCoderFriends::PathUtil
|
10
|
-
|
11
9
|
def code_test(infile)
|
12
|
-
path, _dir, _prg, _base, ext, _q =
|
10
|
+
path, _dir, _prg, _base, ext, _q = ctx.path_info.components
|
13
11
|
lang = lang_id(ext)
|
14
12
|
src = File.read(path, encoding: Encoding::UTF_8)
|
15
13
|
data = File.read(infile)
|
@@ -4,10 +4,8 @@ module AtCoderFriends
|
|
4
4
|
module Scraping
|
5
5
|
# submit sources on submit page
|
6
6
|
module Submission
|
7
|
-
include AtCoderFriends::PathUtil
|
8
|
-
|
9
7
|
def submit
|
10
|
-
path, _dir, prg, _base, ext, q =
|
8
|
+
path, _dir, prg, _base, ext, q = ctx.path_info.components
|
11
9
|
puts "***** submit #{prg} *****"
|
12
10
|
lang = lang_id(ext)
|
13
11
|
src = File.read(path, encoding: Encoding::UTF_8)
|
@@ -8,6 +8,7 @@ module AtCoderFriends
|
|
8
8
|
# run tests for the specified program.
|
9
9
|
class Base
|
10
10
|
include PathUtil
|
11
|
+
|
11
12
|
STATUS_STR = {
|
12
13
|
OK: '<< OK >>'.green,
|
13
14
|
WA: '!!!!! WA !!!!!'.red,
|
@@ -19,7 +20,7 @@ module AtCoderFriends
|
|
19
20
|
|
20
21
|
def initialize(ctx)
|
21
22
|
@ctx = ctx
|
22
|
-
@path, @dir, @prg, @base, @ext, @q =
|
23
|
+
@path, @dir, @prg, @base, @ext, @q = ctx.path_info.components
|
23
24
|
@detail = true
|
24
25
|
end
|
25
26
|
|
@@ -32,11 +33,23 @@ module AtCoderFriends
|
|
32
33
|
end
|
33
34
|
|
34
35
|
def test_loc
|
35
|
-
test_cmd
|
36
|
+
if test_cmd
|
37
|
+
'local'
|
38
|
+
elsif ctx.scraping_agent.respond_to?(:code_test)
|
39
|
+
'remote'
|
40
|
+
else
|
41
|
+
raise AppError, "test_cmd for .#{ext} is not specified."
|
42
|
+
end
|
36
43
|
end
|
37
44
|
|
38
45
|
def test_mtd
|
39
|
-
test_cmd
|
46
|
+
if test_cmd
|
47
|
+
:local_test
|
48
|
+
elsif ctx.scraping_agent.respond_to?(:code_test)
|
49
|
+
:remote_test
|
50
|
+
else
|
51
|
+
raise AppError, "test_cmd for .#{ext} is not specified."
|
52
|
+
end
|
40
53
|
end
|
41
54
|
|
42
55
|
def run_test(id, infile, outfile, expfile)
|
@@ -63,7 +76,7 @@ module AtCoderFriends
|
|
63
76
|
end
|
64
77
|
|
65
78
|
def local_test(infile, outfile)
|
66
|
-
system("#{test_cmd} < #{infile} > #{outfile}")
|
79
|
+
system("#{test_cmd} < \"#{infile}\" > \"#{outfile}\"")
|
67
80
|
end
|
68
81
|
|
69
82
|
def remote_test(infile, outfile)
|
@@ -4,20 +4,18 @@ module AtCoderFriends
|
|
4
4
|
module TestRunner
|
5
5
|
# run test cases for the specified program with judge input/output.
|
6
6
|
class Judge < Base
|
7
|
-
include PathUtil
|
8
|
-
|
9
7
|
attr_reader :data_dir, :result_dir
|
10
8
|
|
11
9
|
def initialize(ctx)
|
12
10
|
super(ctx)
|
13
|
-
@data_dir = cases_dir
|
14
|
-
@result_dir =
|
11
|
+
@data_dir = ctx.path_info.cases_dir
|
12
|
+
@result_dir = ctx.path_info.cases_out_dir
|
15
13
|
end
|
16
14
|
|
17
15
|
def judge_all
|
18
16
|
puts "***** judge_all #{prg} (#{test_loc}) *****"
|
19
|
-
results = Dir["#{data_dir}/#{q}/in
|
20
|
-
id = File.basename(infile
|
17
|
+
results = Dir["#{data_dir}/#{q}/in/*"].sort.map do |infile|
|
18
|
+
id = File.basename(infile)
|
21
19
|
judge(id, false)
|
22
20
|
end
|
23
21
|
!results.empty? && results.all?
|
@@ -30,9 +28,9 @@ module AtCoderFriends
|
|
30
28
|
|
31
29
|
def judge(id, detail = true)
|
32
30
|
@detail = detail
|
33
|
-
infile = "#{data_dir}/#{q}/in/#{id}
|
34
|
-
outfile = "#{result_dir}/#{q}/result/#{id}
|
35
|
-
expfile = "#{data_dir}/#{q}/out/#{id}
|
31
|
+
infile = "#{data_dir}/#{q}/in/#{id}"
|
32
|
+
outfile = "#{result_dir}/#{q}/result/#{id}"
|
33
|
+
expfile = "#{data_dir}/#{q}/out/#{id}"
|
36
34
|
run_test(id, infile, outfile, expfile)
|
37
35
|
end
|
38
36
|
end
|
@@ -4,19 +4,17 @@ module AtCoderFriends
|
|
4
4
|
module TestRunner
|
5
5
|
# run test cases for the specified program with sample input/output.
|
6
6
|
class Sample < Base
|
7
|
-
include PathUtil
|
8
|
-
|
9
7
|
attr_reader :data_dir
|
10
8
|
|
11
9
|
def initialize(ctx)
|
12
10
|
super(ctx)
|
13
|
-
@data_dir = smp_dir
|
11
|
+
@data_dir = ctx.path_info.smp_dir
|
14
12
|
end
|
15
13
|
|
16
14
|
def test_all
|
17
15
|
puts "***** test_all #{prg} (#{test_loc}) *****"
|
18
16
|
results = Dir["#{data_dir}/#{q}_*.in"].sort.map do |infile|
|
19
|
-
id = File.basename(infile, '.in').sub(
|
17
|
+
id = File.basename(infile, '.in').sub(/\A#{q}_/, '')
|
20
18
|
test(id)
|
21
19
|
end
|
22
20
|
!results.empty? && results.all?
|
@@ -10,9 +10,8 @@ module AtCoderFriends
|
|
10
10
|
attr_reader :path, :file, :vdir, :vpath
|
11
11
|
|
12
12
|
def initialize(ctx)
|
13
|
-
@path = ctx.
|
14
|
-
@
|
15
|
-
@vdir = tmp_dir(path)
|
13
|
+
@path, _dir, @file = ctx.path_info.components
|
14
|
+
@vdir = ctx.path_info.tmp_dir
|
16
15
|
@vpath = File.join(vdir, "#{file}.verified")
|
17
16
|
end
|
18
17
|
|
data/lib/at_coder_friends.rb
CHANGED
@@ -4,6 +4,7 @@ require 'at_coder_friends/version'
|
|
4
4
|
require 'at_coder_friends/errors'
|
5
5
|
require 'at_coder_friends/path_util'
|
6
6
|
require 'at_coder_friends/config_loader'
|
7
|
+
require 'at_coder_friends/path_info'
|
7
8
|
require 'at_coder_friends/verifier'
|
8
9
|
require 'at_coder_friends/test_runner/base'
|
9
10
|
require 'at_coder_friends/test_runner/sample'
|
@@ -1,8 +1,8 @@
|
|
1
1
|
// <%= pbm.url %>
|
2
|
-
|
3
2
|
<%
|
4
3
|
if pbm.options.interactive
|
5
|
-
|
4
|
+
%>
|
5
|
+
#include <cstdio>
|
6
6
|
#include <vector>
|
7
7
|
#include <string>
|
8
8
|
|
@@ -33,10 +33,10 @@ void query() {
|
|
33
33
|
}
|
34
34
|
|
35
35
|
//------------------------------------------------------------------------------
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
<% gen_consts.each do |const| %><%= const %>
|
37
|
+
<% end %>
|
38
|
+
<% gen_decls.each do |dcl| %><%= dcl %>
|
39
|
+
<% end %>
|
40
40
|
void solve() {
|
41
41
|
printf("! %s\n", ans);
|
42
42
|
fflush(stdout);
|
@@ -50,23 +50,26 @@ void solve() {
|
|
50
50
|
}
|
51
51
|
|
52
52
|
void input() {
|
53
|
-
|
54
|
-
|
53
|
+
<% gen_inputs.each do |input| %> <%= input %>
|
54
|
+
<% end
|
55
|
+
%>#ifdef DEBUG
|
55
56
|
scanf("%s", source);
|
56
57
|
#endif
|
57
|
-
}
|
58
|
+
}
|
59
|
+
<%
|
58
60
|
else
|
59
|
-
|
61
|
+
%>
|
62
|
+
#include <cstdio>
|
60
63
|
|
61
64
|
using namespace std;
|
62
65
|
|
63
66
|
#define REP(i,n) for(int i=0; i<(int)(n); i++)
|
64
67
|
#define FOR(i,b,e) for(int i=(b); i<=(int)(e); i++)
|
65
68
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
69
|
+
<% gen_consts.each do |const| %><%= const %>
|
70
|
+
<% end %>
|
71
|
+
<% gen_decls.each do |dcl| %><%= dcl %>
|
72
|
+
<% end %>
|
70
73
|
void solve() {
|
71
74
|
<%
|
72
75
|
if (vs = pbm.options.binary_values)
|
@@ -80,11 +83,12 @@ end
|
|
80
83
|
}
|
81
84
|
|
82
85
|
void input() {
|
83
|
-
|
84
|
-
|
86
|
+
<% gen_inputs.each do |input| %> <%= input %>
|
87
|
+
<% end
|
88
|
+
%>}
|
89
|
+
<%
|
85
90
|
end
|
86
91
|
%>
|
87
|
-
|
88
92
|
int main() {
|
89
93
|
input();
|
90
94
|
solve();
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# <%= pbm.url %>
|
2
|
-
|
3
2
|
<%
|
4
3
|
if pbm.options.interactive
|
5
|
-
%>
|
4
|
+
%>
|
5
|
+
def query(*args)
|
6
6
|
puts "? #{args.join(' ')}"
|
7
7
|
STDOUT.flush
|
8
8
|
if $DEBUG
|
@@ -15,10 +15,10 @@ end
|
|
15
15
|
|
16
16
|
$DEBUG = true
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
<% gen_consts.each do |const| %><%= const %>
|
19
|
+
<% end %>
|
20
|
+
<% gen_decls.each do |dcl| %><%= dcl %>
|
21
|
+
<% end %>
|
22
22
|
if $DEBUG
|
23
23
|
@responses = []
|
24
24
|
@source = gets.chomp
|
@@ -35,10 +35,11 @@ if $DEBUG
|
|
35
35
|
puts "----------------------------------------"
|
36
36
|
end<%
|
37
37
|
else
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
%>
|
39
|
+
<% gen_consts.each do |const| %><%= const %>
|
40
|
+
<% end %>
|
41
|
+
<% gen_decls.each do |dcl| %><%= dcl %>
|
42
|
+
<% end %>
|
42
43
|
<%
|
43
44
|
if (vs = pbm.options.binary_values)
|
44
45
|
%>puts cond ? '<%= vs[0] %>' : '<%= vs[1] %>'<%
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: at_coder_friends
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nejiko96
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-03-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colorize
|
@@ -174,6 +174,7 @@ files:
|
|
174
174
|
- lib/at_coder_friends/parser/sample_data.rb
|
175
175
|
- lib/at_coder_friends/parser/section_wrapper.rb
|
176
176
|
- lib/at_coder_friends/parser/sections.rb
|
177
|
+
- lib/at_coder_friends/path_info.rb
|
177
178
|
- lib/at_coder_friends/path_util.rb
|
178
179
|
- lib/at_coder_friends/problem.rb
|
179
180
|
- lib/at_coder_friends/scraping/agent.rb
|
@@ -187,15 +188,6 @@ files:
|
|
187
188
|
- lib/at_coder_friends/test_runner/sample.rb
|
188
189
|
- lib/at_coder_friends/verifier.rb
|
189
190
|
- lib/at_coder_friends/version.rb
|
190
|
-
- tasks/regression/check_const.rake
|
191
|
-
- tasks/regression/check_diff.rake
|
192
|
-
- tasks/regression/check_fmt.rake
|
193
|
-
- tasks/regression/check_parse.rake
|
194
|
-
- tasks/regression/list_handler.rb
|
195
|
-
- tasks/regression/regression.rb
|
196
|
-
- tasks/regression/report_handler.rb
|
197
|
-
- tasks/regression/section_list.rake
|
198
|
-
- tasks/regression/setup.rake
|
199
191
|
- templates/cxx_builtin.cxx.erb
|
200
192
|
- templates/ruby_builtin.rb.erb
|
201
193
|
homepage: https://github.com/nejiko96/at_coder_friends
|
@@ -1,137 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'regression'
|
4
|
-
|
5
|
-
module AtCoderFriends
|
6
|
-
# tasks for regression
|
7
|
-
module Regression
|
8
|
-
module_function
|
9
|
-
|
10
|
-
CONST_PAT = {
|
11
|
-
mod: /
|
12
|
-
(.{,30}(?:
|
13
|
-
で割った|modulo|mod\b|divided\s+by|dividing\s+by
|
14
|
-
).{,30})
|
15
|
-
/xmi,
|
16
|
-
max: /
|
17
|
-
(.{,30}(?:
|
18
|
-
≦|≤|\\le|&leq?;
|
19
|
-
|<|\\lt|<
|
20
|
-
|以上.{1,25}以下の整数
|
21
|
-
).{,30})
|
22
|
-
/xmi
|
23
|
-
}.freeze
|
24
|
-
|
25
|
-
def collect(tgt)
|
26
|
-
open_const_report('collect', tgt) do |f|
|
27
|
-
local_pbm_list.each do |contest, q, url|
|
28
|
-
page = agent.get(url)
|
29
|
-
body = page.body.force_encoding('utf-8')
|
30
|
-
ms = body.scan(CONST_PAT[tgt.to_sym])
|
31
|
-
ms.each do |m|
|
32
|
-
s = m[0].delete("\r\n")
|
33
|
-
f.puts [contest, q, tsv_escape(s)].join("\t")
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def check_mod
|
40
|
-
open_const_report('check', 'mod') do |f|
|
41
|
-
local_pbm_list.each do |contest, q, url|
|
42
|
-
pbm = local_scraping_agent(nil, contest).fetch_problem(q, url)
|
43
|
-
Parser::Sections.process(pbm)
|
44
|
-
Parser::Modulo.process(pbm)
|
45
|
-
pbm.constants.each do |cnst|
|
46
|
-
f.puts [contest, q, cnst.value].join("\t")
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def check_max
|
53
|
-
open_const_report('check', 'max') do |f|
|
54
|
-
local_pbm_list.each do |contest, q, url|
|
55
|
-
pbm = local_scraping_agent(nil, contest).fetch_problem(q, url)
|
56
|
-
Parser::Sections.process(pbm)
|
57
|
-
Parser::Constraints.process(pbm)
|
58
|
-
pbm.constants.each do |cns|
|
59
|
-
f.puts [contest, q, "#{cns.name}:#{cns.value}"].join("\t")
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
def merge_list(tgt)
|
66
|
-
tbl = load_merge_list(tgt)
|
67
|
-
save_merge_list(tgt, tbl)
|
68
|
-
end
|
69
|
-
|
70
|
-
def load_merge_list(tgt)
|
71
|
-
tbl = {}
|
72
|
-
%w[collect check]
|
73
|
-
.map { |act| load_const_report(act, tgt) }
|
74
|
-
.each
|
75
|
-
.with_index(1) do |data, n|
|
76
|
-
data
|
77
|
-
.group_by { |contest, q, _| "#{contest}\t#{q}" }
|
78
|
-
.map { |key, grp| [key, grp.map { |row| row[2] }.join("\n")] }
|
79
|
-
.each do |key, txt|
|
80
|
-
tbl[key] ||= { 'v1' => '', 'v2' => '' }
|
81
|
-
tbl[key]["v#{n}"] = '"' + txt + '"'
|
82
|
-
end
|
83
|
-
end
|
84
|
-
tbl
|
85
|
-
end
|
86
|
-
|
87
|
-
def save_merge_list(tgt, tbl)
|
88
|
-
open_const_report('merge', tgt) do |f|
|
89
|
-
tbl.sort.each do |k, h|
|
90
|
-
f.puts [k, h['v1'], h['v2']].join("\t")
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def open_const_report(act, tgt)
|
96
|
-
open_report("#{act}_#{tgt}.txt") { |f| yield f }
|
97
|
-
end
|
98
|
-
|
99
|
-
def load_const_report(act, tgt)
|
100
|
-
file = report_path("#{act}_#{tgt}.txt")
|
101
|
-
Encoding.default_external = 'utf-8'
|
102
|
-
CSV.read(file, col_sep: "\t", headers: false)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
namespace :regression do
|
108
|
-
desc 'list all mod values'
|
109
|
-
task :collect_mod do
|
110
|
-
AtCoderFriends::Regression.collect('mod')
|
111
|
-
end
|
112
|
-
|
113
|
-
desc 'check extracted mod values'
|
114
|
-
task :check_mod do
|
115
|
-
AtCoderFriends::Regression.check_mod
|
116
|
-
end
|
117
|
-
|
118
|
-
desc 'merge mod values list'
|
119
|
-
task :merge_mod do
|
120
|
-
AtCoderFriends::Regression.merge_list('mod')
|
121
|
-
end
|
122
|
-
|
123
|
-
desc 'list all max values'
|
124
|
-
task :collect_max do
|
125
|
-
AtCoderFriends::Regression.collect('max')
|
126
|
-
end
|
127
|
-
|
128
|
-
desc 'check extracted max values'
|
129
|
-
task :check_max do
|
130
|
-
AtCoderFriends::Regression.check_max
|
131
|
-
end
|
132
|
-
|
133
|
-
desc 'merge max values list'
|
134
|
-
task :merge_max do
|
135
|
-
AtCoderFriends::Regression.merge_list('max')
|
136
|
-
end
|
137
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'regression'
|
4
|
-
|
5
|
-
module AtCoderFriends
|
6
|
-
# tasks for regression
|
7
|
-
module Regression
|
8
|
-
module_function
|
9
|
-
|
10
|
-
def check_diff
|
11
|
-
emit_dir = format(EMIT_DIR_FMT, now: Time.now.strftime('%Y%m%d%H%M%S'))
|
12
|
-
rmdir_force(emit_dir)
|
13
|
-
|
14
|
-
local_pbm_list.each do |contest, q, url|
|
15
|
-
pbm = local_scraping_agent(emit_dir, contest).fetch_problem(q, url)
|
16
|
-
pipeline(pbm)
|
17
|
-
end
|
18
|
-
|
19
|
-
diff_log = report_path('check_diff.txt')
|
20
|
-
system("diff -r --exclude=.git #{EMIT_ORG_DIR} #{emit_dir} > #{diff_log}")
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
namespace :regression do
|
26
|
-
desc 'run regression check'
|
27
|
-
task :check_diff do
|
28
|
-
AtCoderFriends::Regression.check_diff
|
29
|
-
end
|
30
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'regression'
|
4
|
-
|
5
|
-
module AtCoderFriends
|
6
|
-
# tasks for regression
|
7
|
-
module Regression
|
8
|
-
module_function
|
9
|
-
|
10
|
-
def check_fmt
|
11
|
-
open_report('check_fmt.txt') do |f|
|
12
|
-
local_pbm_list.each do |contest, q, url|
|
13
|
-
next unless (res = process_fmt(contest, q, url))
|
14
|
-
|
15
|
-
f.puts [
|
16
|
-
contest, q, *res.map { |s| tsv_escape(s) }
|
17
|
-
].join("\t")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def process_fmt(contest, q, url)
|
23
|
-
pbm = local_scraping_agent(nil, contest).fetch_problem(q, url)
|
24
|
-
Parser::Sections.process(pbm)
|
25
|
-
Parser::SampleData.process(pbm)
|
26
|
-
fmt1 = Parser::InputFormat.find_fmt(pbm)
|
27
|
-
return unless fmt1 && !fmt1.empty?
|
28
|
-
|
29
|
-
fmt2 = Parser::InputFormat.normalize_fmt(fmt1).join("\n")
|
30
|
-
Parser::InputFormat.process(pbm)
|
31
|
-
Parser::InputType.process(pbm)
|
32
|
-
inpdefs = pbm.formats_src
|
33
|
-
fmt3 = inpdefs.map(&:to_s).join("\n")
|
34
|
-
fmt4 = inpdefs.any? { |inpdef| inpdef.cols.empty? } ? '○' : ''
|
35
|
-
[fmt1, fmt2, fmt3, fmt4]
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
namespace :regression do
|
41
|
-
desc 'checks input format patterns'
|
42
|
-
task :check_fmt do
|
43
|
-
AtCoderFriends::Regression.check_fmt
|
44
|
-
end
|
45
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'regression'
|
4
|
-
require 'at_coder_friends'
|
5
|
-
|
6
|
-
module AtCoderFriends
|
7
|
-
# tasks for regression
|
8
|
-
module Regression
|
9
|
-
module_function
|
10
|
-
|
11
|
-
def check_parse
|
12
|
-
list = local_pbm_list.map do |contest, q, url|
|
13
|
-
pbm = local_scraping_agent(nil, contest).fetch_problem(q, url)
|
14
|
-
Parser::Main.process(pbm)
|
15
|
-
flags = [
|
16
|
-
!fmt?(pbm),
|
17
|
-
pbm.samples.all? { |smp| smp.txt.empty? },
|
18
|
-
pbm.options.interactive
|
19
|
-
]
|
20
|
-
[contest, q, flags]
|
21
|
-
end
|
22
|
-
report(list, 'check_parse.txt')
|
23
|
-
end
|
24
|
-
|
25
|
-
def check_bin
|
26
|
-
list = local_pbm_list.map do |contest, q, url|
|
27
|
-
pbm = local_scraping_agent(nil, contest).fetch_problem(q, url)
|
28
|
-
Parser::Main.process(pbm)
|
29
|
-
flags = [pbm.options.binary_values]
|
30
|
-
[contest, q, flags]
|
31
|
-
end
|
32
|
-
report(list, 'check_bin.txt')
|
33
|
-
end
|
34
|
-
|
35
|
-
def fmt?(pbm)
|
36
|
-
fmt = Parser::InputFormat.find_fmt(pbm)
|
37
|
-
fmt && !fmt.empty?
|
38
|
-
end
|
39
|
-
|
40
|
-
def report(list, file)
|
41
|
-
open_report(file) do |f|
|
42
|
-
list
|
43
|
-
.select { |_, _, flags| flags.any? }
|
44
|
-
.map { |c, q, flags| [c, q, flags.map { |flg| f_to_s(flg) }] }
|
45
|
-
.each { |args| f.puts args.flatten.join("\t") }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
def f_to_s(f)
|
50
|
-
if f.is_a?(Array)
|
51
|
-
f
|
52
|
-
else
|
53
|
-
f ? '◯' : '-'
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
namespace :regression do
|
60
|
-
desc 'checks page parse result'
|
61
|
-
task :check_parse do
|
62
|
-
AtCoderFriends::Regression.check_parse
|
63
|
-
end
|
64
|
-
|
65
|
-
desc 'checks binary problem parse result'
|
66
|
-
task :check_bin do
|
67
|
-
AtCoderFriends::Regression.check_bin
|
68
|
-
end
|
69
|
-
end
|
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'net/http'
|
4
|
-
require 'uri'
|
5
|
-
require 'json'
|
6
|
-
require 'csv'
|
7
|
-
|
8
|
-
module AtCoderFriends
|
9
|
-
# tasks for regression
|
10
|
-
module Regression
|
11
|
-
module_function
|
12
|
-
|
13
|
-
CONTEST_LIST_URL = 'https://kenkoooo.com/atcoder/resources/contests.json'
|
14
|
-
ACF_HOME = File.expand_path(File.join(__dir__, '..', '..'))
|
15
|
-
REGRESSION_HOME = File.join(ACF_HOME, 'regression')
|
16
|
-
PAGES_DIR = File.join(REGRESSION_HOME, 'pages')
|
17
|
-
EMIT_ORG_DIR = File.join(REGRESSION_HOME, 'emit_org')
|
18
|
-
EMIT_DIR_FMT = File.join(REGRESSION_HOME, 'emit_%<now>s')
|
19
|
-
|
20
|
-
def contest_id_list
|
21
|
-
uri = URI.parse(CONTEST_LIST_URL)
|
22
|
-
json = Net::HTTP.get(uri)
|
23
|
-
contests = JSON.parse(json)
|
24
|
-
puts "Total #{contests.size} contests"
|
25
|
-
contests.map { |h| h['id'] }
|
26
|
-
end
|
27
|
-
|
28
|
-
def local_pbm_list
|
29
|
-
Dir.glob(PAGES_DIR + '/**/*.html').map do |pbm_path|
|
30
|
-
contest = File.basename(File.dirname(pbm_path))
|
31
|
-
q = File.basename(pbm_path, '.html')
|
32
|
-
url = "file://#{pbm_path}"
|
33
|
-
[contest, q, url]
|
34
|
-
end.sort # .take(10)
|
35
|
-
end
|
36
|
-
|
37
|
-
def pbm_list_from_file(file)
|
38
|
-
dat = File.join(REGRESSION_HOME, file)
|
39
|
-
CSV.read(dat, col_sep: "\t", headers: false).map do |contest, q|
|
40
|
-
pbm_path = File.join(PAGES_DIR, contest, "#{q}.html")
|
41
|
-
url = "file://#{pbm_path}"
|
42
|
-
[contest, q, url]
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
@@ -1,38 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'mechanize'
|
4
|
-
require 'at_coder_friends'
|
5
|
-
require_relative 'list_handler'
|
6
|
-
require_relative 'report_handler'
|
7
|
-
|
8
|
-
module AtCoderFriends
|
9
|
-
# tasks for regression
|
10
|
-
module Regression
|
11
|
-
module_function
|
12
|
-
|
13
|
-
def scraping_agent(root, contest)
|
14
|
-
root ||= REGRESSION_HOME
|
15
|
-
@ctx = Context.new({}, File.join(root, contest))
|
16
|
-
@ctx.scraping_agent
|
17
|
-
end
|
18
|
-
|
19
|
-
def local_scraping_agent(root, contest)
|
20
|
-
scraping_agent(root, contest)
|
21
|
-
.tap { |sa| sa.agent.pre_connect_hooks.clear }
|
22
|
-
end
|
23
|
-
|
24
|
-
def agent
|
25
|
-
@agent ||= Mechanize.new
|
26
|
-
end
|
27
|
-
|
28
|
-
def pipeline(pbm)
|
29
|
-
Parser::Main.process(pbm)
|
30
|
-
@ctx.generator.process(pbm)
|
31
|
-
@ctx.emitter.emit(pbm)
|
32
|
-
end
|
33
|
-
|
34
|
-
def rmdir_force(dir)
|
35
|
-
FileUtils.rm_r(dir) if Dir.exist?(dir)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
@@ -1,20 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module AtCoderFriends
|
4
|
-
# tasks for regression
|
5
|
-
module Regression
|
6
|
-
module_function
|
7
|
-
|
8
|
-
def open_report(file)
|
9
|
-
File.open(report_path(file), 'wb') { |f| yield f }
|
10
|
-
end
|
11
|
-
|
12
|
-
def report_path(file)
|
13
|
-
File.join(REGRESSION_HOME, file)
|
14
|
-
end
|
15
|
-
|
16
|
-
def tsv_escape(str)
|
17
|
-
'"' + str.gsub('"', '""').gsub("\t", ' ') + '"'
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'regression'
|
4
|
-
|
5
|
-
module AtCoderFriends
|
6
|
-
# tasks for regression
|
7
|
-
module Regression
|
8
|
-
module_function
|
9
|
-
|
10
|
-
SectionInfo = Struct.new(:contest, :q, :title)
|
11
|
-
|
12
|
-
def section_list
|
13
|
-
list = load_section_list
|
14
|
-
save_section_list(list)
|
15
|
-
end
|
16
|
-
|
17
|
-
def load_section_list
|
18
|
-
local_pbm_list.flat_map do |contest, q, url|
|
19
|
-
page = agent.get(url)
|
20
|
-
%w[h2 h3].flat_map do |tag|
|
21
|
-
page.search(tag).map do |h|
|
22
|
-
SectionInfo.new(contest, q, normalize(h.content))
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
def save_section_list(list)
|
29
|
-
open_report('section_list.txt') do |f|
|
30
|
-
list.group_by(&:title).each do |k, vs|
|
31
|
-
f.puts [k, vs.size, vs[0].contest, vs[0].q].join("\t")
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def normalize(s)
|
37
|
-
s
|
38
|
-
.tr('0-9A-Za-z', '0-9A-Za-z')
|
39
|
-
.gsub(/[[:space:]]/, '')
|
40
|
-
.gsub(/[^一-龠_ぁ-ん_ァ-ヶーa-zA-Z0-9 ]/, '')
|
41
|
-
.downcase
|
42
|
-
.gsub(/\d+/, '{N}')
|
43
|
-
.strip
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
namespace :regression do
|
49
|
-
desc 'list all section titles'
|
50
|
-
task :section_list do
|
51
|
-
AtCoderFriends::Regression.section_list
|
52
|
-
end
|
53
|
-
end
|
data/tasks/regression/setup.rake
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require_relative 'regression'
|
4
|
-
|
5
|
-
module AtCoderFriends
|
6
|
-
# tasks for regression
|
7
|
-
module Regression
|
8
|
-
module_function
|
9
|
-
|
10
|
-
def setup
|
11
|
-
rmdir_force(PAGES_DIR)
|
12
|
-
rmdir_force(EMIT_ORG_DIR)
|
13
|
-
contest_id_list.each do |contest|
|
14
|
-
setup_by_contest(contest)
|
15
|
-
sleep 3
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def setup_by_contest(contest)
|
20
|
-
scraping_agent(EMIT_ORG_DIR, contest).fetch_all do |pbm|
|
21
|
-
setup_by_pbm(contest, pbm)
|
22
|
-
end
|
23
|
-
rescue StandardError => e
|
24
|
-
p e
|
25
|
-
end
|
26
|
-
|
27
|
-
def setup_by_pbm(contest, pbm)
|
28
|
-
html_path = File.join(PAGES_DIR, contest, "#{pbm.q}.html")
|
29
|
-
save_file(html_path, pbm.page.body)
|
30
|
-
pipeline(pbm)
|
31
|
-
rescue StandardError => e
|
32
|
-
p e
|
33
|
-
end
|
34
|
-
|
35
|
-
def save_file(path, content)
|
36
|
-
dir = File.dirname(path)
|
37
|
-
FileUtils.makedirs(dir) unless Dir.exist?(dir)
|
38
|
-
File.binwrite(path, content)
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
namespace :regression do
|
44
|
-
desc 'setup regression environment'
|
45
|
-
task :setup do
|
46
|
-
AtCoderFriends::Regression.setup
|
47
|
-
end
|
48
|
-
end
|