at_coder_friends 0.5.2 → 0.6.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.
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