mgmg 1.4.2 → 1.5.2

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.
data/lib/mgmg/search.rb CHANGED
@@ -1,288 +1,260 @@
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:)
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:)
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:)
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:)
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:)
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:)
199
+ opt.smith_max, opt.armor_max = sa_search(para, target, opt.comp_min, opt:)
200
+ opt.smith_min, opt.armor_min = sa_search(para, target, opt.comp_max, 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:)
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:)
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
+ if a.kind_of?(Recipe)
232
+ opt_a = a.option.dup
233
+ a = a.recipe
234
+ else
235
+ opt_a = opt_a.dup.set_default(a)
236
+ end
237
+ if b.kind_of?(Recipe)
238
+ opt_b = b.option.dup
239
+ b = b.recipe
240
+ else
241
+ opt_b = opt_b.dup.set_default(b)
242
+ end
243
+ sca, scb = a.search(para, start, opt: opt_a), b.search(para, start, opt: opt_b)
271
244
  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
245
+ if eb < ea || ( ea == eb && opt_a.irep.para_call(para, *sca) < opt_b.irep.para_call(para, *scb) )
246
+ a, b, opt_a, opt_b, sca, scb, ea, eb = b, a, opt_b, opt_a, scb, sca, eb, ea
275
247
  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)
248
+ tag = opt_a.irep.para_call(para, *sca) + 1
249
+ sca, scb = a.search(para, term, opt: opt_a), b.search(para, term, opt: opt_b)
278
250
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
279
- if ea < eb || ( ea == eb && irb.para_call(para, *scb) < ira.para_call(para, *sca) )
251
+ if ea < eb || ( ea == eb && opt_b.irep.para_call(para, *scb) < opt_a.irep.para_call(para, *sca) )
280
252
  raise Mgmg::SearchCutException
281
253
  end
282
254
  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)
255
+ sca, scb = a.search(para, tag, opt: opt_a), b.search(para, tag, opt: opt_b)
284
256
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
285
- pa, pb = ira.para_call(para, *sca), irb.para_call(para, *scb)
257
+ pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
286
258
  if eb < ea
287
259
  return [tag-1, pb]
288
260
  elsif ea == eb
@@ -298,65 +270,75 @@ module Mgmg
298
270
  raise UnexpectedError
299
271
  end
300
272
 
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: [])
273
+ module_function def find_upperbound(a, b, para, start, term, opt_a: Option.new, opt_b: Option.new)
302
274
  if start <= term
303
275
  raise ArgumentError, "term < start is needed, (start, term) = (#{start}, #{term}) are given"
304
276
  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)
277
+ if a.kind_of?(Recipe)
278
+ opt_a = a.option.dup
279
+ a = a.recipe
280
+ else
281
+ opt_a = opt_a.dup.set_default(a)
282
+ end
283
+ if b.kind_of?(Recipe)
284
+ opt_b = b.option.dup
285
+ b = b.recipe
286
+ else
287
+ opt_b = opt_b.dup.set_default(b)
288
+ end
289
+ sca, scb = a.search(para, start, opt: opt_a), b.search(para, start, opt: opt_b)
307
290
  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
291
+ if ea < eb || ( ea == eb && opt_b.irep.para_call(para, *scb) < opt_a.irep.para_call(para, *sca) )
292
+ a, b, opt_a, opt_b, sca, scb, ea, eb = b, a, opt_b, opt_a, scb, sca, eb, ea
311
293
  end
312
- tagu = ira.para_call(para, *sca)
294
+ tagu = opt_a.irep.para_call(para, *sca)
313
295
  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)
296
+ tagl = opt_a.irep.para_call(para, *sca)
297
+ sca, scb = a.search(para, term, opt: opt_a), b.search(para, term, opt: opt_b)
316
298
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
317
- if eb < ea || ( ea == eb && ira.para_call(para, *sca) < irb.para_call(para, *scb) )
299
+ if eb < ea || ( ea == eb && opt_a.irep.para_call(para, *sca) < opt_b.irep.para_call(para, *scb) )
318
300
  raise Mgmg::SearchCutException
319
301
  end
320
302
  while term < tagu
321
303
  ret = nil
322
- sca = a.search(para, tagl, smith_min_a, armor_min_a, min_smith: min_smith, irep: ira)
304
+ sca = a.search(para, tagl, opt: opt_a)
323
305
  next_tagu, next_sca = tagl, sca
324
- scb = b.search(para, tagl, smith_min_b, armor_min_b, min_smith: min_smith, irep: irb)
306
+ scb = b.search(para, tagl, opt: opt_b)
325
307
  while tagl < tagu
326
308
  ea, eb = Mgmg.exp(*sca), Mgmg.exp(*scb)
327
- pa, pb = ira.para_call(para, *sca), irb.para_call(para, *scb)
309
+ pa, pb = opt_a.irep.para_call(para, *sca), opt_b.irep.para_call(para, *scb)
328
310
  if ea < eb
329
311
  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)
312
+ sca = a.search(para, pa + 1, opt: opt_a)
313
+ tagl = opt_a.irep.para_call(para, *sca)
314
+ scb = b.search(para, tagl, opt: opt_b)
333
315
  elsif ea == eb
334
316
  if pb < pa
335
317
  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)
318
+ sca = a.search(para, pa + 1, opt: opt_a)
319
+ tagl = opt_a.irep.para_call(para, *sca)
320
+ scb = b.search(para, tagl, opt: opt_b)
339
321
  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)
322
+ scb = b.search(para, pb + 1, opt: opt_b)
323
+ tagl = opt_b.irep.para_call(para, *scb)
324
+ sca = a.search(para, tagl, opt: opt_a)
343
325
  end
344
326
  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)
327
+ sca = a.search(para, pa + 1, opt: opt_a)
328
+ tagl = opt_a.irep.para_call(para, *sca)
329
+ scb = b.search(para, tagl, opt: opt_b)
348
330
  end
349
331
  end
350
332
  if ret.nil?
351
333
  tagu = next_tagu
352
334
  next_sca[-1] -= 2
353
- tagl = ira.para_call(para, *next_sca)
335
+ tagl = opt_a.irep.para_call(para, *next_sca)
354
336
  if tagl == tagu
355
337
  tagl = term
356
338
  end
357
339
  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))
340
+ pa = opt_a.irep.para_call(para, *a.search(para, ret+1, opt: opt_a))
341
+ pb = opt_b.irep.para_call(para, *b.search(para, ret+1, opt: opt_b))
360
342
  return [ret, [pa, pb].min]
361
343
  end
362
344
  end
@@ -323,4 +323,8 @@ module Mgmg
323
323
  SystemEquip.store(k.sub(/脛当て\Z/, 'すね当て'), SystemEquip[k])
324
324
  end
325
325
  end
326
+ SystemEquipRegexp = Hash.new
327
+ SystemEquip.each_key do |k|
328
+ SystemEquipRegexp.store(k, Regexp.compile(k).freeze)
329
+ end
326
330
  end