at_coder_friends 0.5.2 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -0
  3. data/.rubocop_todo.yml +1 -4
  4. data/Gemfile.lock +1 -1
  5. data/README.md +1 -1
  6. data/config/default.yml +3 -0
  7. data/docs/CONFIGURATION.md +74 -9
  8. data/lib/at_coder_friends.rb +10 -5
  9. data/lib/at_coder_friends/cli.rb +2 -5
  10. data/lib/at_coder_friends/context.rb +4 -0
  11. data/lib/at_coder_friends/emitter.rb +2 -2
  12. data/lib/at_coder_friends/generator/cxx_builtin.rb +191 -0
  13. data/lib/at_coder_friends/generator/main.rb +53 -0
  14. data/lib/at_coder_friends/generator/ruby_builtin.rb +128 -0
  15. data/lib/at_coder_friends/parser/binary.rb +39 -0
  16. data/lib/at_coder_friends/parser/constraints.rb +36 -0
  17. data/lib/at_coder_friends/parser/{format_parser.rb → input_format.rb} +42 -30
  18. data/lib/at_coder_friends/parser/interactive.rb +29 -0
  19. data/lib/at_coder_friends/parser/main.rb +6 -3
  20. data/lib/at_coder_friends/parser/sample_data.rb +24 -0
  21. data/lib/at_coder_friends/parser/section_wrapper.rb +49 -0
  22. data/lib/at_coder_friends/parser/{page_parser.rb → sections.rb} +44 -50
  23. data/lib/at_coder_friends/problem.rb +40 -24
  24. data/lib/at_coder_friends/scraping/agent.rb +1 -5
  25. data/lib/at_coder_friends/scraping/authentication.rb +2 -2
  26. data/lib/at_coder_friends/scraping/session.rb +1 -1
  27. data/lib/at_coder_friends/scraping/tasks.rb +2 -6
  28. data/lib/at_coder_friends/test_runner/base.rb +36 -31
  29. data/lib/at_coder_friends/test_runner/judge.rb +2 -6
  30. data/lib/at_coder_friends/test_runner/sample.rb +8 -6
  31. data/lib/at_coder_friends/version.rb +1 -1
  32. data/tasks/regression/check_diff.rake +29 -0
  33. data/tasks/regression/check_parse.rake +56 -0
  34. data/tasks/regression/regression.rb +67 -0
  35. data/tasks/regression/section_list.rake +41 -0
  36. data/tasks/regression/setup.rake +48 -0
  37. data/templates/cxx_builtin_default.cxx +26 -0
  38. data/templates/cxx_builtin_interactive.cxx +61 -0
  39. data/templates/ruby_builtin_default.rb +5 -0
  40. data/templates/ruby_builtin_interactive.rb +32 -0
  41. metadata +21 -8
  42. data/lib/at_coder_friends/cxx_generator.rb +0 -169
  43. data/lib/at_coder_friends/parser/constraints_parser.rb +0 -26
  44. data/lib/at_coder_friends/ruby_generator.rb +0 -97
  45. data/tasks/regression.rake +0 -163
@@ -0,0 +1,41 @@
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 section_list
11
+ list = local_pbm_list.flat_map do |contest, q, url|
12
+ page = agent.get(url)
13
+ %w[h2 h3].flat_map do |tag|
14
+ page.search(tag).map do |h|
15
+ { contest: contest, q: q, text: normalize(h.content) }
16
+ end
17
+ end
18
+ end
19
+ list.group_by { |sec| sec[:text] }.each do |k, vs|
20
+ puts [k, vs.size, vs[0][:contest], vs[0][:q]].join("\t")
21
+ end
22
+ end
23
+
24
+ def normalize(s)
25
+ s
26
+ .tr(' 0-9A-Za-z', ' 0-9A-Za-z')
27
+ .gsub(/[^一-龠_ぁ-ん_ァ-ヶーa-zA-Z0-9 ]/, '')
28
+ .gsub(/\d+/, '{N}')
29
+ .gsub(' ', '')
30
+ .downcase
31
+ .strip
32
+ end
33
+ end
34
+ end
35
+
36
+ namespace :regression do
37
+ desc 'list all section titles'
38
+ task :section_list do
39
+ AtCoderFriends::Regression.section_list
40
+ end
41
+ end
@@ -0,0 +1,48 @@
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
@@ -0,0 +1,26 @@
1
+ // /*** URL ***/
2
+
3
+ #include <cstdio>
4
+
5
+ using namespace std;
6
+
7
+ #define REP(i,n) for(int i=0; i<(int)(n); i++)
8
+ #define FOR(i,b,e) for(int i=(b); i<=(int)(e); i++)
9
+
10
+ /*** CONSTS ***/
11
+
12
+ /*** DCLS ***/
13
+
14
+ void solve() {
15
+ /*** OUTPUT ***/
16
+ }
17
+
18
+ void input() {
19
+ /*** INPUTS ***/
20
+ }
21
+
22
+ int main() {
23
+ input();
24
+ solve();
25
+ return 0;
26
+ }
@@ -0,0 +1,61 @@
1
+ // /*** URL ***/
2
+
3
+ #include <cstdio>
4
+ #include <vector>
5
+ #include <string>
6
+
7
+ using namespace std;
8
+
9
+ #define DEBUG
10
+ #define REP(i,n) for(int i=0; i<(int)(n); i++)
11
+ #define FOR(i,b,e) for(int i=(b); i<=(int)(e); i++)
12
+
13
+ //------------------------------------------------------------------------------
14
+ const int BUFSIZE = 1024;
15
+ char req[BUFSIZE];
16
+ char res[BUFSIZE];
17
+ #ifdef DEBUG
18
+ char source[BUFSIZE];
19
+ vector<string> responses;
20
+ #endif
21
+
22
+ void query() {
23
+ printf("? %s\n", req);
24
+ fflush(stdout);
25
+ #ifdef DEBUG
26
+ sprintf(res, "generate response from source");
27
+ responses.push_back(res);
28
+ #else
29
+ scanf("%s", res);
30
+ #endif
31
+ }
32
+
33
+ //------------------------------------------------------------------------------
34
+ /*** CONSTS ***/
35
+
36
+ /*** DCLS ***/
37
+
38
+ void solve() {
39
+ printf("! %s\n", ans);
40
+ fflush(stdout);
41
+ #ifdef DEBUG
42
+ printf("query count: %d\n", responses.size());
43
+ puts("query results:");
44
+ REP(i, responses.size()) {
45
+ puts(responses[i].c_str());
46
+ }
47
+ #endif
48
+ }
49
+
50
+ void input() {
51
+ /*** INPUTS ***/
52
+ #ifdef DEBUG
53
+ scanf("%s", source);
54
+ #endif
55
+ }
56
+
57
+ int main() {
58
+ input();
59
+ solve();
60
+ return 0;
61
+ }
@@ -0,0 +1,5 @@
1
+ # ### URL ###
2
+
3
+ ### DCLS ###
4
+
5
+ ### OUTPUT ###
@@ -0,0 +1,32 @@
1
+ # ### URL ###
2
+
3
+ def query(*args)
4
+ puts "? #{args.join(' ')}"
5
+ STDOUT.flush
6
+ if $DEBUG
7
+ res = 'generate response from @source'
8
+ res.tap { |res| @responses << res }
9
+ else
10
+ gets.chomp
11
+ end
12
+ end
13
+
14
+ $DEBUG = true
15
+
16
+ ### DCLS ###
17
+
18
+ if $DEBUG
19
+ @responses = []
20
+ @source = gets.chomp
21
+ end
22
+
23
+ puts "! #{ans}"
24
+ STDOUT.flush
25
+
26
+ if $DEBUG
27
+ puts "----------------------------------------"
28
+ puts "query count: #{@responses.size}"
29
+ puts "query results:"
30
+ @responses.each { |res| puts res }
31
+ puts "----------------------------------------"
32
+ end
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.5.2
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - nejiko96
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-10-14 00:00:00.000000000 Z
11
+ date: 2019-10-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -156,16 +156,21 @@ files:
156
156
  - lib/at_coder_friends/cli.rb
157
157
  - lib/at_coder_friends/config_loader.rb
158
158
  - lib/at_coder_friends/context.rb
159
- - lib/at_coder_friends/cxx_generator.rb
160
159
  - lib/at_coder_friends/emitter.rb
161
160
  - lib/at_coder_friends/errors.rb
162
- - lib/at_coder_friends/parser/constraints_parser.rb
163
- - lib/at_coder_friends/parser/format_parser.rb
161
+ - lib/at_coder_friends/generator/cxx_builtin.rb
162
+ - lib/at_coder_friends/generator/main.rb
163
+ - lib/at_coder_friends/generator/ruby_builtin.rb
164
+ - lib/at_coder_friends/parser/binary.rb
165
+ - lib/at_coder_friends/parser/constraints.rb
166
+ - lib/at_coder_friends/parser/input_format.rb
167
+ - lib/at_coder_friends/parser/interactive.rb
164
168
  - lib/at_coder_friends/parser/main.rb
165
- - lib/at_coder_friends/parser/page_parser.rb
169
+ - lib/at_coder_friends/parser/sample_data.rb
170
+ - lib/at_coder_friends/parser/section_wrapper.rb
171
+ - lib/at_coder_friends/parser/sections.rb
166
172
  - lib/at_coder_friends/path_util.rb
167
173
  - lib/at_coder_friends/problem.rb
168
- - lib/at_coder_friends/ruby_generator.rb
169
174
  - lib/at_coder_friends/scraping/agent.rb
170
175
  - lib/at_coder_friends/scraping/authentication.rb
171
176
  - lib/at_coder_friends/scraping/custom_test.rb
@@ -177,7 +182,15 @@ files:
177
182
  - lib/at_coder_friends/test_runner/sample.rb
178
183
  - lib/at_coder_friends/verifier.rb
179
184
  - lib/at_coder_friends/version.rb
180
- - tasks/regression.rake
185
+ - tasks/regression/check_diff.rake
186
+ - tasks/regression/check_parse.rake
187
+ - tasks/regression/regression.rb
188
+ - tasks/regression/section_list.rake
189
+ - tasks/regression/setup.rake
190
+ - templates/cxx_builtin_default.cxx
191
+ - templates/cxx_builtin_interactive.cxx
192
+ - templates/ruby_builtin_default.rb
193
+ - templates/ruby_builtin_interactive.rb
181
194
  homepage: https://github.com/nejiko96/at_coder_friends
182
195
  licenses:
183
196
  - MIT
@@ -1,169 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module AtCoderFriends
4
- # generates C++ source code from definition
5
- class CxxGenerator
6
- TEMPLATE = <<~TEXT
7
- #include <cstdio>
8
-
9
- using namespace std;
10
-
11
- #define REP(i,n) for(int i=0; i<(int)(n); i++)
12
- #define FOR(i,b,e) for(int i=(b); i<=(int)(e); i++)
13
-
14
- /*** CONSTS ***/
15
-
16
- /*** DCLS ***/
17
-
18
- void solve() {
19
- int ans = 0;
20
- printf("%d\\n", ans);
21
- }
22
-
23
- void input() {
24
- /*** READS ***/
25
- }
26
-
27
- int main() {
28
- input();
29
- solve();
30
- return 0;
31
- }
32
- TEXT
33
-
34
- SCANF_FMTS = [
35
- 'scanf("%<fmt>s", %<addr>s);',
36
- 'REP(i, %<sz1>s) scanf("%<fmt>s", %<addr>s);',
37
- 'REP(i, %<sz1>s) REP(j, %<sz2>s) scanf("%<fmt>s", %<addr>s);'
38
- ].freeze
39
-
40
- FMT_FMTS = { number: '%d', string: '%s', char: '%s' }.freeze
41
-
42
- ADDR_FMTS = {
43
- single: {
44
- number: '&%<v>s',
45
- string: '%<v>s'
46
- },
47
- harray: {
48
- number: '%<v>s + i',
49
- string: '%<v>s[i]',
50
- char: '%<v>s'
51
- },
52
- varray: {
53
- number: '%<v>s + i',
54
- string: '%<v>s[i]'
55
- },
56
- matrix: {
57
- number: '&%<v>s[i][j]',
58
- string: '%<v>s[i][j]',
59
- char: '%<v>s[i]'
60
- }
61
- }.freeze
62
-
63
- def process(pbm)
64
- src = generate(pbm.defs, pbm.constraints)
65
- pbm.add_src(:cxx, src)
66
- end
67
-
68
- def generate(defs, constraints)
69
- consts = gen_consts(constraints)
70
- dcls = gen_decls(defs)
71
- reads = gen_reads(defs)
72
- TEMPLATE
73
- .sub('/*** CONSTS ***/', consts.join("\n"))
74
- .sub('/*** DCLS ***/', dcls.join("\n"))
75
- .sub('/*** READS ***/', reads.map { |s| ' ' + s }.join("\n"))
76
- end
77
-
78
- def gen_consts(constraints)
79
- constraints
80
- .select { |c| c.type == :max }
81
- .map { |c| "const int #{c.name.upcase}_MAX = #{c.value};" }
82
- end
83
-
84
- def gen_decls(defs)
85
- defs.map { |inpdef| gen_decl(inpdef) }.flatten
86
- end
87
-
88
- def gen_decl(inpdef)
89
- case inpdef.container
90
- when :single
91
- gen_single_decl(inpdef)
92
- when :harray
93
- gen_harray_decl(inpdef)
94
- when :varray
95
- gen_varray_decl(inpdef)
96
- when :matrix
97
- gen_matrix_decl(inpdef)
98
- end
99
- end
100
-
101
- def gen_single_decl(inpdef)
102
- names = inpdef.names
103
- case inpdef.item
104
- when :number
105
- dcl = names.join(', ')
106
- "int #{dcl};"
107
- when :string
108
- names.map { |v| "char #{v}[#{v.upcase}_MAX + 1];" }
109
- end
110
- end
111
-
112
- def gen_harray_decl(inpdef)
113
- v = inpdef.names[0]
114
- sz = gen_arr_size(inpdef.size)[0]
115
- case inpdef.item
116
- when :number
117
- "int #{v}[#{sz}];"
118
- when :string
119
- "char #{v}[#{sz}][#{v.upcase}_MAX + 1];"
120
- when :char
121
- "char #{v}[#{sz} + 1];"
122
- end
123
- end
124
-
125
- def gen_varray_decl(inpdef)
126
- names = inpdef.names
127
- sz = gen_arr_size(inpdef.size)[0]
128
- case inpdef.item
129
- when :number
130
- names.map { |v| "int #{v}[#{sz}];" }
131
- when :string
132
- names.map { |v| "char #{v}[#{sz}][#{v.upcase}_MAX + 1];" }
133
- end
134
- end
135
-
136
- def gen_matrix_decl(inpdef)
137
- v = inpdef.names[0]
138
- sz1, sz2 = gen_arr_size(inpdef.size)
139
- case inpdef.item
140
- when :number
141
- "int #{v}[#{sz1}][#{sz2}];"
142
- when :string
143
- "char #{v}[#{sz1}][#{sz2}][#{v.upcase}_MAX + 1];"
144
- when :char
145
- "char #{v}[#{sz1}][#{sz2} + 1];"
146
- end
147
- end
148
-
149
- def gen_arr_size(szs)
150
- szs.map { |sz| sz =~ /\D/ ? "#{sz.upcase}_MAX" : sz }
151
- end
152
-
153
- def gen_reads(defs)
154
- defs.map { |inpdef| gen_read(inpdef) }.flatten
155
- end
156
-
157
- # rubocop:disable Metrics/AbcSize
158
- def gen_read(inpdef)
159
- dim = inpdef.size.size - (inpdef.item == :char ? 1 : 0)
160
- scanf = SCANF_FMTS[dim]
161
- sz1, sz2 = inpdef.size
162
- fmt = FMT_FMTS[inpdef.item] * inpdef.names.size
163
- addr_fmt = ADDR_FMTS[inpdef.container][inpdef.item]
164
- addr = inpdef.names.map { |v| format(addr_fmt, v: v) }.join(', ')
165
- format(scanf, sz1: sz1, sz2: sz2, fmt: fmt, addr: addr)
166
- end
167
- # rubocop:enable Metrics/AbcSize
168
- end
169
- end