mgmg 1.4.2 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/mgmg/search.rb CHANGED
@@ -1,288 +1,249 @@
1
1
  class String
2
- def smith_search(para, target, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
3
- irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
4
- if smith_min.nil?
5
- if min_smith
6
- smith_min = self.min_smith.min_smith
7
- else
8
- smith_min = build(-1, -1, left_associative: left_associative).min_level
9
- end
10
- end
11
- if smith_max < smith_min
12
- raise ArgumentError, "smith_min <= smith_max is needed, (smith_min, smith_max) = (#{smith_min}, #{smith_max}) are given"
13
- elsif cut_exp < Float::INFINITY
2
+ def smith_search(para, target, comp, opt: Mgmg::Option.new)
3
+ opt = opt.dup.set_default(self)
4
+ if opt.smith_max < opt.smith_min
5
+ raise ArgumentError, "smith_min <= smith_max is needed, (smith_min, smith_max) = (#{opt.smith_min}, #{opt.smith_max}) are given"
6
+ elsif opt.cut_exp < Float::INFINITY
14
7
  begin
15
- smith_max = [smith_max, Mgmg.invexp2(cut_exp, comp)].min
8
+ opt.smith_max = [opt.smith_max, Mgmg.invexp2(opt.cut_exp, comp)].min
16
9
  rescue
17
10
  raise Mgmg::SearchCutException
18
11
  end
19
12
  end
20
- if target <= irep.para_call(para, smith_min, comp)
21
- return smith_min
22
- elsif irep.para_call(para, smith_max, comp) < target
13
+ if target <= opt.irep.para_call(para, opt.smith_min, comp)
14
+ return opt.smith_min
15
+ elsif opt.irep.para_call(para, opt.smith_max, comp) < target
23
16
  raise Mgmg::SearchCutException
24
17
  end
25
- while 1 < smith_max - smith_min do
26
- smith = (smith_max - smith_min).div(2) + smith_min
27
- if irep.para_call(para, smith, comp) < target
28
- smith_min = smith
18
+ while 1 < opt.smith_max - opt.smith_min do
19
+ smith = (opt.smith_max - opt.smith_min).div(2) + opt.smith_min
20
+ if opt.irep.para_call(para, smith, comp) < target
21
+ opt.smith_min = smith
29
22
  else
30
- smith_max = smith
23
+ opt.smith_max = smith
31
24
  end
32
25
  end
33
- smith_max
26
+ opt.smith_max
34
27
  end
35
- def comp_search(para, target, smith, comp_min=nil, comp_max=10000, left_associative: true, irep: nil, reinforcement: [])
36
- irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
37
- comp_min = min_comp(left_associative: left_associative)
38
- if comp_max < comp_min
39
- raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{comp_min}, #{comp_max}) are given"
40
- end
41
- if target <= irep.para_call(para, smith, comp_min)
42
- return comp_min
43
- elsif irep.para_call(para, smith, comp_max) < target
28
+ def comp_search(para, target, smith, opt: Mgmg::Option.new)
29
+ opt = opt.dup.set_default(self)
30
+ if opt.comp_max < opt.comp_min
31
+ raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{opt.comp_min}, #{opt.comp_max}) are given"
32
+ end
33
+ if target <= opt.irep.para_call(para, smith, opt.comp_min)
34
+ return opt.comp_min
35
+ elsif opt.irep.para_call(para, smith, opt.comp_max) < target
44
36
  raise Mgmg::SearchCutException
45
37
  end
46
- while 1 < comp_max - comp_min do
47
- comp = (comp_max - comp_min).div(2) + comp_min
48
- if irep.para_call(para, smith, comp) < target
49
- comp_min = comp
38
+ while 1 < opt.comp_max - opt.comp_min do
39
+ comp = (opt.comp_max - opt.comp_min).div(2) + opt.comp_min
40
+ if opt.irep.para_call(para, smith, comp) < target
41
+ opt.comp_min = comp
50
42
  else
51
- comp_max = comp
43
+ opt.comp_max = comp
52
44
  end
53
45
  end
54
- comp_max
46
+ opt.comp_max
55
47
  end
56
- def search(para, target, smith_min=nil, comp_min=nil, smith_max=10000, comp_max=10000, left_associative: true, step: 1, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
57
- irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
58
- if smith_min.nil?
59
- if min_smith
60
- smith_min = self.min_smith
61
- else
62
- smith_min = build(-1, -1, left_associative: left_associative).min_level
63
- end
64
- end
65
- comp_min = min_comp(left_associative: left_associative) if comp_min.nil?
66
- comp_min = comp_search(para, target, smith_max, comp_min, comp_max, left_associative: left_associative, irep: irep)
67
- smith_max = smith_search(para, target, comp_min, smith_min, smith_max, left_associative: left_associative, irep: irep)
68
- smith_min = smith_search(para, target, comp_max, smith_min, smith_max, left_associative: left_associative, irep: irep)
69
- raise Mgmg::SearchCutException if cut_exp < Mgmg.exp(smith_min, comp_min)
70
- comp_max = comp_search(para, target, smith_min, comp_min, comp_max, left_associative: left_associative, irep: irep)
71
- minex, ret = Mgmg.exp(smith_min, comp_max), [smith_min, comp_max]
72
- exp = Mgmg.exp(smith_max, comp_min)
73
- minex, ret = exp, [smith_max, comp_min] if exp < minex
74
- (comp_min+step).step(comp_max-1, step) do |comp|
75
- break if minex < Mgmg.exp(smith_min, comp)
76
- smith = smith_search(para, target, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
48
+ def search(para, target, opt: Mgmg::Option.new)
49
+ opt = opt.dup.set_default(self)
50
+ opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
51
+ opt.comp_min = comp_search(para, target, opt.smith_max, opt: opt)
52
+ opt.smith_max = smith_search(para, target, opt.comp_min, opt: opt_nocut)
53
+ opt.smith_min = smith_search(para, target, opt.comp_max, opt: opt_nocut)
54
+ raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.comp_min)
55
+ opt.comp_max = comp_search(para, target, opt.smith_min, opt: opt)
56
+ ret = nil
57
+ exp = Mgmg.exp(opt.smith_min, opt.comp_max)
58
+ opt.cut_exp, ret = exp, [opt.smith_min, opt.comp_max] if exp < opt.cut_exp
59
+ exp = Mgmg.exp(opt.smith_max, opt.comp_min)
60
+ opt.cut_exp, ret = exp, [opt.smith_max, opt.comp_min] if exp < opt.cut_exp
61
+ (opt.comp_min+opt.step).step(opt.comp_max-1, opt.step) do |comp|
62
+ break if opt.cut_exp < Mgmg.exp(opt.smith_min, comp)
63
+ smith = smith_search(para, target, comp, opt: opt)
77
64
  exp = Mgmg.exp(smith, comp)
78
- if exp < minex
79
- minex, ret = exp, [smith, comp]
80
- elsif exp == minex
81
- if irep.para_call(para, *ret) < irep.para_call(para, smith, comp)
65
+ if exp < opt.cut_exp
66
+ opt.cut_exp, ret = exp, [smith, comp]
67
+ elsif exp == opt.cut_exp
68
+ if ret.nil? or opt.irep.para_call(para, *ret) < opt.irep.para_call(para, smith, comp) then
82
69
  ret = [smith, comp]
83
70
  end
84
71
  end
85
72
  rescue Mgmg::SearchCutException
86
73
  end
87
- raise Mgmg::SearchCutException, "the result exceeds given cut_exp=#{cut_exp}" if cut_exp < minex
74
+ raise Mgmg::SearchCutException, "the result exceeds given cut_exp=#{opt.cut_exp}" if ret.nil?
88
75
  ret
89
76
  end
90
77
  end
91
78
  module Enumerable
92
- def smith_search(para, target, armor, comp, smith_min=nil, smith_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
93
- irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
94
- if smith_min.nil?
95
- if min_smith
96
- smith_min = self.min_smith[0]
97
- else
98
- smith_min = build(-1, -1, -1, left_associative: left_associative).min_level[0]
99
- end
100
- end
101
- if smith_max < smith_min
102
- raise ArgumentError, "smith_min <= smith_max is needed, (smith_min, smith_max) = (#{smith_min}, #{smith_max}) are given"
103
- elsif cut_exp < Float::INFINITY
79
+ def smith_search(para, target, armor, comp, opt: Mgmg::Option.new)
80
+ opt = opt.dup.set_default(self)
81
+ if opt.smith_max < opt.smith_min
82
+ raise ArgumentError, "smith_min <= smith_max is needed, (smith_min, smith_max) = (#{opt.smith_min}, #{opt.smith_max}) are given"
83
+ elsif opt.cut_exp < Float::INFINITY
104
84
  begin
105
- smith_max = [smith_max, Mgmg.invexp3(cut_exp, armor, comp)].min
85
+ opt.smith_max = [opt.smith_max, Mgmg.invexp3(opt.cut_exp, armor, comp)].min
106
86
  rescue
107
87
  raise Mgmg::SearchCutException
108
88
  end
109
89
  end
110
- if irep.para_call(para, smith_max, armor, comp) < target
90
+ if opt.irep.para_call(para, opt.smith_max, armor, comp) < target
111
91
  raise Mgmg::SearchCutException
112
- elsif target <= irep.para_call(para, smith_min, armor, comp)
113
- return smith_min
92
+ elsif target <= opt.irep.para_call(para, opt.smith_min, armor, comp)
93
+ return opt.smith_min
114
94
  end
115
- while 1 < smith_max - smith_min do
116
- smith = (smith_max - smith_min).div(2) + smith_min
117
- if irep.para_call(para, smith, armor, comp) < target
118
- smith_min = smith
95
+ while 1 < opt.smith_max - opt.smith_min do
96
+ smith = (opt.smith_max - opt.smith_min).div(2) + opt.smith_min
97
+ if opt.irep.para_call(para, smith, armor, comp) < target
98
+ opt.smith_min = smith
119
99
  else
120
- smith_max = smith
100
+ opt.smith_max = smith
121
101
  end
122
102
  end
123
- smith_max
103
+ opt.smith_max
124
104
  end
125
- def armor_search(para, target, smith, comp, armor_min=nil, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
126
- irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
127
- if armor_min.nil?
128
- if min_smith
129
- armor_min = self.min_smith[1]
130
- else
131
- armor_min = build(-1, -1, -1, left_associative: left_associative).min_level[1]
132
- end
133
- end
134
- if armor_max < armor_min
135
- raise ArgumentError, "armor_min <= armor_max is needed, (armor_min, armor_max) = (#{armor_min}, #{armor_max}) are given"
136
- elsif cut_exp < Float::INFINITY
105
+ def armor_search(para, target, smith, comp, opt: Mgmg::Option.new)
106
+ opt = opt.dup.set_default(self)
107
+ if opt.armor_max < opt.armor_min
108
+ raise ArgumentError, "armor_min <= armor_max is needed, (armor_min, armor_max) = (#{opt.armor_min}, #{opt.armor_max}) are given"
109
+ elsif opt.cut_exp < Float::INFINITY
137
110
  begin
138
- armor_max = [armor_max, Mgmg.invexp3(cut_exp, smith, comp)].min
111
+ opt.armor_max = [opt.armor_max, Mgmg.invexp3(opt.cut_exp, smith, comp)].min
139
112
  rescue
140
113
  raise Mgmg::SearchCutException
141
114
  end
142
115
  end
143
- if irep.para_call(para, smith, armor_max, comp) < target
116
+ if opt.irep.para_call(para, smith, opt.armor_max, comp) < target
144
117
  raise Mgmg::SearchCutException
145
- elsif target <= irep.para_call(para, smith, armor_min, comp)
146
- return armor_min
118
+ elsif target <= opt.irep.para_call(para, smith, opt.armor_min, comp)
119
+ return opt.armor_min
147
120
  end
148
- while 1 < armor_max - armor_min do
149
- armor = (armor_max - armor_min).div(2) + armor_min
150
- if irep.para_call(para, smith, armor, comp) < target
151
- armor_min = armor
121
+ while 1 < opt.armor_max - opt.armor_min do
122
+ armor = (opt.armor_max - opt.armor_min).div(2) + opt.armor_min
123
+ if opt.irep.para_call(para, smith, armor, comp) < target
124
+ opt.armor_min = armor
152
125
  else
153
- armor_max = armor
126
+ opt.armor_max = armor
154
127
  end
155
128
  end
156
- armor_max
129
+ opt.armor_max
157
130
  end
158
- def sa_search(para, target, comp, smith_min=nil, armor_min=nil, smith_max=10000, armor_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
159
- irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
160
- if min_smith
161
- s, a = self.min_smith
162
- else
163
- s, a = build(-1, -1, -1, left_associative: left_associative).min_level
164
- end
165
- smith_min = s if smith_min.nil?
166
- armor_min = a if armor_min.nil?
167
- smith_min = smith_search(para, target, armor_max, comp, smith_min, smith_max, left_associative: true, irep: irep)
168
- armor_min = armor_search(para, target, smith_max, comp, armor_min, armor_max, left_associative: true, irep: irep)
169
- raise Mgmg::SearchCutException if cut_exp < Mgmg.exp(smith_min, armor_min, comp)
170
- smith_max = smith_search(para, target, armor_min, comp, smith_min, smith_max, left_associative: true, irep: irep)
171
- armor_max = armor_search(para, target, smith_min, comp, armor_min, armor_max, left_associative: true, irep: irep)
172
- minex, ret = Mgmg.exp(smith_min, armor_max, comp), [smith_min, armor_max]
173
- exp = Mgmg.exp(smith_max, armor_min, comp)
174
- if exp < minex
175
- minex, ret = exp, [smith_max, armor_min]
176
- (armor_min+1).upto(armor_max-1) do |armor|
177
- break if minex < Mgmg.exp(smith_min, armor, comp)
178
- smith = smith_search(para, target, armor, comp, smith_min, smith_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
131
+ def sa_search(para, target, comp, opt: Mgmg::Option.new)
132
+ opt = opt.dup.set_default(self)
133
+ opt_nocut = opt.dup; opt_nocut.cut_exp = Float::INFINITY
134
+ opt.smith_min = smith_search(para, target, opt.armor_max, comp, opt: opt_nocut)
135
+ opt.armor_min = armor_search(para, target, opt.smith_max, comp, opt: opt_nocut)
136
+ raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, comp)
137
+ opt.smith_max = smith_search(para, target, opt.armor_min, comp, opt: opt_nocut)
138
+ opt.armor_max = armor_search(para, target, opt.smith_min, comp, opt: opt_nocut)
139
+ ret = nil
140
+ exp = Mgmg.exp(opt.smith_min, opt.armor_max, comp)
141
+ opt.cut_exp, ret = exp, [opt.smith_min, opt.armor_max] if exp < opt.cut_exp
142
+ exp2 = Mgmg.exp(opt.smith_max, opt.armor_min, comp)
143
+ if exp2 < exp
144
+ opt.cut_exp, ret = exp2, [opt.smith_max, opt.armor_min] if exp2 < opt.cut_exp
145
+ (opt.armor_min+1).upto(opt.armor_max-1) do |armor|
146
+ break if opt.cut_exp < Mgmg.exp(opt.smith_min, armor, comp)
147
+ smith = smith_search(para, target, armor, comp, opt: opt)
179
148
  exp = Mgmg.exp(smith, armor, comp)
180
- if exp < minex
181
- minex, ret = exp, [smith, armor]
182
- elsif exp == minex
183
- if irep.para_call(para, *ret, comp) < irep.para_call(para, smith, armor, comp)
149
+ if exp < opt.cut_exp
150
+ opt.cut_exp, ret = exp, [smith, armor]
151
+ elsif exp == opt.cut_exp
152
+ if ret.nil? or opt.irep.para_call(para, *ret, comp) < opt.irep.para_call(para, smith, armor, comp) then
184
153
  ret = [smith, armor]
185
154
  end
186
155
  end
187
156
  rescue Mgmg::SearchCutException
188
157
  end
189
158
  else
190
- (smith_min+1).upto(smith_max-1) do |smith|
191
- break if minex < Mgmg.exp(smith, armor_min, comp)
192
- armor = armor_search(para, target, smith, comp, armor_min, armor_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
159
+ (opt.smith_min+1).upto(opt.smith_max-1) do |smith|
160
+ break if opt.cut_exp < Mgmg.exp(smith, opt.armor_min, comp)
161
+ armor = armor_search(para, target, smith, comp, opt: opt)
193
162
  exp = Mgmg.exp(smith, armor, comp)
194
- if exp < minex
195
- minex, ret = exp, [smith, armor]
196
- elsif exp == minex
197
- if irep.para_call(para, *ret, comp) < irep.para_call(para, smith, armor, comp)
163
+ if exp < opt.cut_exp
164
+ opt.cut_exp, ret = exp, [smith, armor]
165
+ elsif exp == opt.cut_exp
166
+ if ret.nil? or opt.irep.para_call(para, *ret, comp) < opt.irep.para_call(para, smith, armor, comp) then
198
167
  ret = [smith, armor]
199
168
  end
200
169
  end
201
170
  rescue Mgmg::SearchCutException
202
171
  end
203
172
  end
204
- raise Mgmg::SearchCutException if cut_exp < minex
173
+ raise Mgmg::SearchCutException if ret.nil?
205
174
  ret
206
175
  end
207
- def comp_search(para, target, smith, armor, comp_min=nil, comp_max=10000, left_associative: true, irep: nil, reinforcement: [])
208
- irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
209
- comp_min = min_comp(left_associative: left_associative)
210
- if comp_max < comp_min
211
- raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{comp_min}, #{comp_max}) are given"
212
- end
213
- if target <= irep.para_call(para, smith, armor, comp_min)
214
- return comp_min
215
- elsif irep.para_call(para, smith, armor, comp_max) < target
216
- raise ArgumentError, "given comp_max=#{comp_max} does not satisfies the target"
217
- end
218
- while 1 < comp_max - comp_min do
219
- comp = (comp_max - comp_min).div(2) + comp_min
220
- if irep.para_call(para, smith, armor, comp) < target
221
- comp_min = comp
176
+ def comp_search(para, target, smith, armor, opt: Mgmg::Option.new)
177
+ opt = opt.dup.set_default(self)
178
+ if opt.comp_max < opt.comp_min
179
+ raise ArgumentError, "comp_min <= comp_max is needed, (comp_min, comp_max) = (#{opt.comp_min}, #{opt.comp_max}) are given"
180
+ end
181
+ if target <= opt.irep.para_call(para, smith, armor, opt.comp_min)
182
+ return opt.comp_min
183
+ elsif opt.irep.para_call(para, smith, armor, opt.comp_max) < target
184
+ raise ArgumentError, "given comp_max=#{opt.comp_max} does not satisfies the target"
185
+ end
186
+ while 1 < opt.comp_max - opt.comp_min do
187
+ comp = (opt.comp_max - opt.comp_min).div(2) + opt.comp_min
188
+ if opt.irep.para_call(para, smith, armor, comp) < target
189
+ opt.comp_min = comp
222
190
  else
223
- comp_max = comp
191
+ opt.comp_max = comp
224
192
  end
225
193
  end
226
- comp_max
194
+ opt.comp_max
227
195
  end
228
- def search(para, target, smith_min=nil, armor_min=nil, comp_min=nil, smith_max=10000, armor_max=10000, comp_max=10000, left_associative: true, cut_exp: Float::INFINITY, min_smith: false, irep: nil, reinforcement: [])
229
- irep = ir(left_associative: left_associative, reinforcement: reinforcement) if irep.nil?
230
- if min_smith
231
- s, a = self.min_smith
232
- else
233
- s, a = build(-1, -1, -1, left_associative: left_associative).min_level
234
- end
235
- smith_min = s if smith_min.nil?
236
- armor_min = a if armor_min.nil?
237
- comp_min = min_comp(left_associative: left_associative) if comp_min.nil?
238
- comp_min = comp_search(para, target, smith_max, armor_max, comp_min, comp_max, left_associative: left_associative, irep: irep)
239
- smith_max, armor_max = sa_search(para, target, comp_min, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative, irep: irep)
240
- smith_min, armor_min = sa_search(para, target, comp_max, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative, irep: irep)
241
- raise Mgmg::SearchCutException if cut_exp < Mgmg.exp(smith_min, armor_min, comp_min)
242
- comp_max = comp_search(para, target, smith_min, armor_min, comp_min, comp_max, left_associative: left_associative, irep: irep)
243
- minex, ret = Mgmg.exp(smith_min, armor_min, comp_max), [smith_min, armor_min, comp_max]
244
- exp = Mgmg.exp(smith_max, armor_max, comp_min)
245
- minex, ret = exp, [smith_max, armor_max, comp_min] if exp < minex
246
- (comp_min+1).upto(comp_max-1) do |comp|
247
- break if minex < Mgmg.exp(smith_min, armor_min, comp)
248
- smith, armor = sa_search(para, target, comp, smith_min, armor_min, smith_max, armor_max, left_associative: left_associative, cut_exp: [minex, cut_exp].min, irep: irep)
196
+ def search(para, target, opt: Mgmg::Option.new)
197
+ opt = opt.dup.set_default(self)
198
+ opt.comp_min = comp_search(para, target, opt.smith_max, opt.armor_max, opt: opt)
199
+ opt.smith_max, opt.armor_max = sa_search(para, target, opt.comp_min, opt: opt)
200
+ opt.smith_min, opt.armor_min = sa_search(para, target, opt.comp_max, opt: opt)
201
+ raise Mgmg::SearchCutException if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, opt.comp_min)
202
+ opt.comp_max = comp_search(para, target, opt.smith_min, opt.armor_min, opt: opt)
203
+ ret = nil
204
+ exp = Mgmg.exp(opt.smith_min, opt.armor_min, opt.comp_max)
205
+ opt.cut_exp, ret = exp, [opt.smith_min, opt.armor_min,opt. comp_max] if exp < opt.cut_exp
206
+ exp = Mgmg.exp(opt.smith_max, opt.armor_max, opt.comp_min)
207
+ opt.cut_exp, ret = exp, [opt.smith_max, opt.armor_max, opt.comp_min] if exp < opt.cut_exp
208
+ (opt.comp_min+1).upto(opt.comp_max-1) do |comp|
209
+ break if opt.cut_exp < Mgmg.exp(opt.smith_min, opt.armor_min, comp)
210
+ smith, armor = sa_search(para, target, comp, opt: opt)
249
211
  exp = Mgmg.exp(smith, armor, comp)
250
- if exp < minex
251
- minex, ret = exp, [smith, armor, comp]
252
- elsif exp == minex
253
- if irep.para_call(para, *ret) < irep.para_call(para, smith, armor, comp)
212
+ if exp < opt.cut_exp
213
+ opt.cut_exp, ret = exp, [smith, armor, comp]
214
+ elsif exp == opt.cut_exp
215
+ if ret.nil? or opt.irep.para_call(para, *ret) < opt.irep.para_call(para, smith, armor, comp) then
254
216
  ret = [smith, armor, comp]
255
217
  end
256
218
  end
257
219
  rescue Mgmg::SearchCutException
258
220
  end
259
- raise Mgmg::SearchCutException, "the result exceeds given cut_exp=#{cut_exp}" if cut_exp < minex
221
+ raise Mgmg::SearchCutException, "the result exceeds given cut_exp=#{opt.cut_exp}" if ret.nil?
260
222
  ret
261
223
  end
262
224
  end
263
225
 
264
226
  module Mgmg
265
- module_function def find_lowerbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false, reinforcement: [])
227
+ module_function def find_lowerbound(a, b, para, start, term, opt_a: Option.new, opt_b: Option.new)
266
228
  if term <= start
267
229
  raise ArgumentError, "start < term is needed, (start, term) = (#{start}, #{term}) are given"
268
230
  end
269
- ira, irb = a.ir(reinforcement: reinforcement), b.ir(reinforcement: reinforcement)
270
- sca, scb = a.search(para, start, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, start, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
231
+ opt_a, opt_b = opt_a.dup.set_default(a), opt_b.dup.set_default(b)
232
+ sca, scb = a.search(para, start, opt: opt_a), b.search(para, start, opt: opt_b)
271
233
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
272
- if eb < ea || ( ea == eb && ira.para_call(para, *sca) < irb.para_call(para, *scb) )
273
- a, b, ira, irb, sca, scb, ea, eb = b, a, irb, ira, scb, sca, eb, ea
274
- smith_min_a, smith_min_b, armor_min_a, armor_min_b = smith_min_b, smith_min_a, armor_min_b, armor_min_a
234
+ if eb < ea || ( ea == eb && opt_a.irep.para_call(para, *sca) < opt_b.irep.para_call(para, *scb) )
235
+ a, b, opt_a, opt_b, sca, scb, ea, eb = b, a, opt_b, opt_a, scb, sca, eb, ea
275
236
  end
276
- tag = ira.para_call(para, *sca) + 1
277
- sca, scb = a.search(para, term, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, term, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
237
+ tag = opt_a.irep.para_call(para, *sca) + 1
238
+ sca, scb = a.search(para, term, opt: opt_a), b.search(para, term, opt: opt_b)
278
239
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
279
- if ea < eb || ( ea == eb && irb.para_call(para, *scb) < ira.para_call(para, *sca) )
240
+ if ea < eb || ( ea == eb && opt_b.irep.para_call(para, *scb) < opt_a.irep.para_call(para, *sca) )
280
241
  raise Mgmg::SearchCutException
281
242
  end
282
243
  while tag < term
283
- sca, scb = a.search(para, tag, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, tag, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
244
+ sca, scb = a.search(para, tag, opt: opt_a), b.search(para, tag, opt: opt_b)
284
245
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
285
- pa, pb = ira.para_call(para, *sca), irb.para_call(para, *scb)
246
+ pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
286
247
  if eb < ea
287
248
  return [tag-1, pb]
288
249
  elsif ea == eb
@@ -298,65 +259,64 @@ module Mgmg
298
259
  raise UnexpectedError
299
260
  end
300
261
 
301
- module_function def find_upperbound(a, b, para, start, term, smith_min_a: nil, smith_min_b: nil, armor_min_a: nil, armor_min_b: nil, min_smith: false, reinforcement: [])
262
+ module_function def find_upperbound(a, b, para, start, term, opt_a: Option.new, opt_b: Option.new)
302
263
  if start <= term
303
264
  raise ArgumentError, "term < start is needed, (start, term) = (#{start}, #{term}) are given"
304
265
  end
305
- ira, irb = a.ir(reinforcement: reinforcement), b.ir(reinforcement: reinforcement)
306
- sca, scb = a.search(para, start, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, start, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
266
+ opt_a, opt_b = opt_a.dup.set_default(a), opt_b.dup.set_default(b)
267
+ sca, scb = a.search(para, start, opt: opt_a), b.search(para, start, opt: opt_b)
307
268
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
308
- if ea < eb || ( ea == eb && irb.para_call(para, *scb) < ira.para_call(para, *sca) )
309
- a, b, ira, irb, sca, scb, ea, eb = b, a, irb, ira, scb, sca, eb, ea
310
- smith_min_a, smith_min_b, armor_min_a, armor_min_b = smith_min_b, smith_min_a, armor_min_b, armor_min_a
269
+ if ea < eb || ( ea == eb && opt_b.irep.para_call(para, *scb) < opt_a.irep.para_call(para, *sca) )
270
+ a, b, opt_a, opt_b, sca, scb, ea, eb = b, a, opt_b, opt_a, scb, sca, eb, ea
311
271
  end
312
- tagu = ira.para_call(para, *sca)
272
+ tagu = opt_a.irep.para_call(para, *sca)
313
273
  sca[-1] -= 2
314
- tagl = ira.para_call(para, *sca)
315
- sca, scb = a.search(para, term, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira), b.search(para, term, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
274
+ tagl = opt_a.irep.para_call(para, *sca)
275
+ sca, scb = a.search(para, term, opt: opt_a), b.search(para, term, opt: opt_b)
316
276
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
317
- if eb < ea || ( ea == eb && ira.para_call(para, *sca) < irb.para_call(para, *scb) )
277
+ if eb < ea || ( ea == eb && opt_a.irep.para_call(para, *sca) < opt_b.irep.para_call(para, *scb) )
318
278
  raise Mgmg::SearchCutException
319
279
  end
320
280
  while term < tagu
321
281
  ret = nil
322
- sca = a.search(para, tagl, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
282
+ sca = a.search(para, tagl, opt: opt_a)
323
283
  next_tagu, next_sca = tagl, sca
324
- scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
284
+ scb = b.search(para, tagl, opt: opt_b)
325
285
  while tagl < tagu
326
286
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
327
- pa, pb = ira.para_call(para, *sca), irb.para_call(para, *scb)
287
+ pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
328
288
  if ea < eb
329
289
  ret = tagl
330
- sca = a.search(para, pa + 1, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
331
- tagl = ira.para_call(para, *sca)
332
- scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
290
+ sca = a.search(para, pa + 1, opt: opt_a)
291
+ tagl = opt_a.irep.para_call(para, *sca)
292
+ scb = b.search(para, tagl, opt: opt_b)
333
293
  elsif ea == eb
334
294
  if pb < pa
335
295
  ret = tagl
336
- sca = a.search(para, pa + 1, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
337
- tagl = ira.para_call(para, *sca)
338
- scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
296
+ sca = a.search(para, pa + 1, opt: opt_a)
297
+ tagl = opt_a.irep.para_call(para, *sca)
298
+ scb = b.search(para, tagl, opt: opt_b)
339
299
  else
340
- scb = b.search(para, pb + 1, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
341
- tagl = irb.para_call(para, *scb)
342
- sca = a.search(para, tagl, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
300
+ scb = b.search(para, pb + 1, opt: opt_b)
301
+ tagl = opt_b.irep.para_call(para, *scb)
302
+ sca = a.search(para, tagl, opt: opt_a)
343
303
  end
344
304
  else
345
- sca = a.search(para, pa + 1, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
346
- tagl = ira.para_call(para, *sca)
347
- scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
305
+ sca = a.search(para, pa + 1, opt: opt_a)
306
+ tagl = opt_a.irep.para_call(para, *sca)
307
+ scb = b.search(para, tagl, opt: opt_b)
348
308
  end
349
309
  end
350
310
  if ret.nil?
351
311
  tagu = next_tagu
352
312
  next_sca[-1] -= 2
353
- tagl = ira.para_call(para, *next_sca)
313
+ tagl = opt_a.irep.para_call(para, *next_sca)
354
314
  if tagl == tagu
355
315
  tagl = term
356
316
  end
357
317
  else
358
- pa = ira.para_call(para, *a.search(para, ret+1, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira))
359
- pb = irb.para_call(para, *b.search(para, ret+1, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb))
318
+ pa = opt_a.irep.para_call(para, *a.search(para, ret+1, opt: opt_a))
319
+ pb = opt_b.irep.para_call(para, *b.search(para, ret+1, opt: opt_b))
360
320
  return [ret, [pa, pb].min]
361
321
  end
362
322
  end
@@ -323,4 +323,10 @@ module Mgmg
323
323
  SystemEquip.store(k.sub(/脛当て\Z/, 'すね当て'), SystemEquip[k])
324
324
  end
325
325
  end
326
+ SystemEquip.freeze
327
+ SystemEquipRegexp = Hash.new
328
+ SystemEquip.keys.each do |k|
329
+ SystemEquipRegexp.store(k.freeze, Regexp.compile(k))
330
+ end
331
+ SystemEquipRegexp.freeze
326
332
  end
data/lib/mgmg/utils.rb CHANGED
@@ -71,6 +71,13 @@ module Mgmg
71
71
  end
72
72
  attr_accessor :equip
73
73
  end
74
+ class InvalidReinforcementNameError < StandardError
75
+ def initialize(str)
76
+ @name = str
77
+ super("Unknown skill or preset cuisine name `#{@name}' is given.")
78
+ end
79
+ attr_accessor :name
80
+ end
74
81
  class SearchCutException < StandardError; end
75
82
  class UnexpectedError < StandardError
76
83
  def initialize()
@@ -116,7 +123,7 @@ module Mgmg
116
123
  Math.sqrt(exp - ((sa-1)**2) - (2*((comp-1)**2)) - 4).round + 1
117
124
  end
118
125
 
119
- CharacterList = /[^\(\)\+0123456789\[\]あきくしすたてなねのびりるイウガクグサジスタダチツデトドニノフブペボムラリルロンヴー一万二光兜典刀剣劣匠双古名吹咆品哮地大天太子安宝小帽弓弩当息悪戦手指斧書服木本杖業樹歴殺水氷法火炎牙物玉王産用界異的皮盾短石砕竜紫綿耳聖脛腕腿般良色衣袋覇質軍軽輝輪重量金鉄鎧闇陽靴額飾首骨鬼龍]/
126
+ CharacterList = /[^\(\)\+0123456789\[\]あきくしすたてなねのびりるイウガクグサジスタダチツデトドニノフブペボムラリルロンヴー一万二光兜典刀剣劣匠双古名吹咆品哮地大天太子安宝小帽弓弩当息悪戦手指斧書服木本杖業樹歴殺水氷法火炎牙物玉王産用界異的皮盾短石砕竜紫綿耳聖脛腕腿般良色衣袋覇質軍軽輝輪重量金鉄鎧闇陽靴額飾首骨鬼龍]/.freeze
120
127
  module_function def check_string(str)
121
128
  str = str.gsub(/[\s \\]/, '')
122
129
  if m = CharacterList.match(str)
@@ -159,7 +166,7 @@ module Mgmg
159
166
  end
160
167
  str
161
168
  end
162
-
169
+
163
170
  module_function def parse_material(str)
164
171
  m = /\A.+?(\d+)\Z/.match(str)
165
172
  mat = MaterialIndex[str.to_sym]
data/lib/mgmg/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mgmg
2
- VERSION = "1.4.2"
2
+ VERSION = "1.5.0"
3
3
  end